c++ - DeleteInterpProc called with active evals -
i writing program executes tcl scripts. when script has exit
command, program crashes error
deleteinterpproc called active evals aborted
i calling tcl_evalfile(m_interpreter, script.c_str())
script file name. have tried tcl_eval
arguments interpreter , "source filename". result same. other tcl comands (eg. puts) interpreter executes normally. how can fixed?
#include <tcl.h> #include <iostream> int main() { tcl_interp *interp = tcl_createinterp(); //tcl_preserve(interp); tcl_eval (interp, "exit"); //tcl_release(interp); std::cout << "11111111111" << std::endl; return 0; }
this simple case. "11111111111" not printed. understand whole program exited when calling tcl_eval (interp, "exit");
. result same after adding tcl_preserve
, tcl_release
.
the problem interpreter, execution context tcl code, getting feet deleted out under itself; makes confused! @ least you're getting clean panic/abort rather disgusting hard-to-reproduce crash.
the easiest fix do:
tcl_preserve(m_interpreter); // code calls tcl_evalfile(m_interpreter, script.c_str()) // , deals results. tcl_release(m_interpreter);
be aware after tcl_release
, tcl_interp
handle may refer deleted memory. (yes, wrapping tcl_preserve
/tcl_release
in raii goodness reasonable.)
if want instead permit code run after script exit
, have take additional steps. in particular, standard tcl exit
command not designed cause return calling context: will cause process call _exit(2)
system call. change it's behavior, replace it:
// callback function implements replacement static int myreplacementexit(clientdata unused, tcl_interp *interp, int argc, const char *argv[]) { // ought check argument count... why bother? tcl_deleteinterp(interp); return tcl_ok; } int main() { tcl_interp *interp = tcl_createinterp(); // install function on standard [exit] tcl_createcommand(interp, "exit", myreplacementexit, null, null); // important; need keep *handle* live until we're finished tcl_preserve(interp); // or run whatever code want here... tcl_eval(interp, "exit"); // important piece of cleanup code if (!tcl_interpdeleted(interp)) tcl_deleteinterp(interp); tcl_release(interp); // after point, *must not* use interp std::cout << "11111111111" << std::endl; return 0; }
the rules doing memory management in these sorts of scenarios laid out in the manual page tcl_createinterp
. (that's 8.6 manual page, relevant rules have been true since @ least tcl 7.0, on 2 decades ago.) once interpreter deleted, can no longer count on executing commands or accessing variables in it; tcl library handles state unwinding you.
Comments
Post a Comment