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