I am writing a program which executes tcl scripts. When the script has exit command, the program crashes with this error
DeleteInterpProc called with active evals
Aborted
I am calling Tcl_EvalFile(m_interpreter, script.c_str()) where script is the file name.
Also I have tried Tcl_Eval with arguments interpreter and "source filename". Result is the same. Other tcl comands (eg. puts) interpreter executes normally. How this can be 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 is the simple case. "11111111111" are not printed. As I understand whole program is exited when calling Tcl_Eval (interp, "exit");. The result is same after adding Tcl_Preserve and Tcl_Release.
The problem is that the interpreter, the execution context for Tcl code, is getting its feet deleted out from under itself; this makes it very confused! At least you're getting a clean panic/abort rather than a disgusting hard-to-reproduce crash.
The easiest fix is probably to do:
Tcl_Preserve(m_interpreter);
// Your code that calls Tcl_EvalFile(m_interpreter, script.c_str())
// and deals with the results.
Tcl_Release(m_interpreter);
Be aware that after the Tcl_Release, the Tcl_Interp handle may refer to deleted memory.
(Yes, wrapping the Tcl_Preserve/Tcl_Release in RAII goodness is reasonable.)
If you want instead to permit your code to run after the script does an exit, you have to take additional steps. In particular, the standard Tcl exit command is not designed to cause a return to the calling context: it will cause the process to call the _exit(2) system call. To change it's behavior, replace it:
// A callback function that implements the replacement
static int
MyReplacementExit(ClientData unused, Tcl_Interp *interp, int argc, const char *argv[])
{
// We ought to check the argument count... but why bother?
Tcl_DeleteInterp(interp);
return TCL_OK;
}
int main() {
Tcl_Interp *interp = Tcl_CreateInterp();
// Install that function over the standard [exit]
Tcl_CreateCommand(interp, "exit", MyReplacementExit, NULL, NULL);
// Important; need to keep the *handle* live until we're finished
Tcl_Preserve(interp);
// Or run whatever code you want here...
Tcl_Eval(interp, "exit");
// Important piece of cleanup code
if (!Tcl_InterpDeleted(interp))
Tcl_DeleteInterp(interp);
Tcl_Release(interp);
// After this point, you *MUST NOT* use interp
std::cout << "11111111111" << std::endl;
return 0;
}
The rules for doing memory management in these sorts of scenarios are laid out in the manual page for Tcl_CreateInterp. (That's the 8.6 manual page, but the relevant rules have been true since at least Tcl 7.0, which is over 2 decades ago.) Once an interpreter is deleted, you can no longer count on executing any commands or accessing any variables in it; the Tcl library handles the state unwinding for you.
It might be better to replace (hide) the exit command and create your own exit command that exit your program gracefully. I'm not that good with C and the Tcl C Api, but I hope this can help you.
Eggdrop for example uses the die command to exit gracefully.
Related
Hello i'm newbie in C++ specially on STL,
I need to create a function with an infinite loop to calculate and process big data (such as Genetic Algorithm), but i also need keep Ui responsive and update it within (after each round) that infinite loop and start/stop operation manually.
something like this:
bool working = false;
void do_process()
{
while(working)
{
// do some stuff
}
}
void btnStart()
{
working = true;
do_process();
}
void btnEnd()
{
working = false;
}
would you please guide me to a proper solution without any 3rdparty lib, thanks.
and apologies for terrible English.
The code below should get you started. But be careful, implementing a multi-threading application is generally a hard problem also for experienced users. Lot of knowledge is required about memory access synchronization and deadlock analysis. Consider the example below is really essential. For instance, in btnStart and btnStop you should check if a thread is already running. Checking the global bool working may require synchronization. Similarly, checking for null pointer may require synchronization. Bottom line, it is way more complicate than it may seem.
#include <iostream>
#include <utility>
#include <thread>
#include <chrono>
#include <memory>
bool working = false;
std::unique_ptr<std::thread> t;
void do_process()
{
while(working)
{
std::cout << "Hi. I am a secondary thread and I am running.\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
void btnStart()
{
working = true;
t.reset(new std::thread(do_process)); // start the thread
}
void btnEnd()
{
working = false; // inform the thread of termination
t->join(); // wait for thread termination
t.reset(NULL);
}
int main()
{
std::cout << "Hi, I am the main thread.\n";
std::cout << "I'll now launch another thread and sleep for a while\n";
btnStart();
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
btnEnd();
std::cout << "What happened while I was slepping?\n";
return 0;
}
I am fairly new also to c++ but i have something that might help.
when i want to run something like an update to my code or to run something external without cramming my original project with code, i like to use ShellExecute to run another c++ program or external program. To use ShellExecute you need #include<windows.h>
For example if i want to update my program, i use #include<fstream>, #include<windows.h>, and #include<string> to check for a value in a file called 'updatereq.txt' (i make it my self). And in my program i run ifstream to check in the file if there is a '1'. If the if statement detects '1' it does this:
void Update(string filename)
{
ShellExecute(NULL,"open",filename.c_str(),NULL,NULL,SW_SHOWNORMAL)
}
This will run with:
HWND set as NULL, Operation set as: "open", File set as string:filenameconstant, Parameters set as NULL, Directory set as NULL(will run in the Directory of originally launching, usually at the main file), and Mode set as SW_SHOWNORMAL which will run it infront of you normally. This is also SW_SHOWMINIMIZED and SW_SHOWMAXIMIZED
Hope this helps!
PS: Remember to mention the file / program name that you are going to run when calling this function
Consider the following scenario:
BOOST_AUTO_TEST_SUITE(suite1)
{
BOOST_AUTO_TEST_CASE(case1)
{
//my test code here
}
}
BOOST_AUTO_TEST_SUITE(suite2)
{
BOOST_AUTO_TEST_CASE(case1)
{
//my test code here
}
BOOST_AUTO_TEST_CASE(case2)
{
//my test code here
}
}
Now, if I want to run suite1/case1 and suite2/case2 at once, I try the following command line argument:
MyProject.exe --run_test="suite1/case1, suite2/case2"
But this doesn't seem to run.
I know that I can separately run these test cases, as:
MyProject.exe --run_test="suite1/case1"
and
MyProject.exe --run_test="suite2/case2"
But I want to run them together at one go. What should I do?
Thanks in advance :)
This is not a feature currently supported by Boost.Test. The documentation states that you can use a comma separated list if the tests are in the same suite:
Running multiple test cases residing within the same test suite by listing their names in coma separated list.
You can also use wildcards to select suites and test cases, but depending on the names of your suites and cases, you may not be able to limit the selection to just to two cases you desire.
http://www.boost.org/doc/libs/1_55_0/libs/test/doc/html/utf/user-guide/runtime-config/run-by-name.html
Edit It seems I might have taken the question title a bit too literally. Running tests simultaneously means "in parallel" to me.
Anyways, if you are happy to run suite2/case1 as well, you can just
MyProject.exe --run_test="suite1,suite2"
See it Live On Coliru too.
Old answer: What is wrong with running the two processes in parallel? By all means, uncomplicate!
However, if you insist, you can fork copies of the main process:
#include <sys/types.h>
#include <sys/wait.h>
#include <iostream>
static int relay_unit_test_main(std::vector<std::string> args);
int main()
{
if (int const child_pid = fork())
{
int exit_code = relay_unit_test_main({"--run_test=suite1"});
int child_status;
while (-1 == waitpid(child_pid, &child_status, 0));
if (!WIFEXITED(child_status)) {
std::cerr << "Child process (" << child_pid << ") failed" << std::endl;
return 1;
}
return exit_code? exit_code : WEXITSTATUS(child_status);
} else
{
return relay_unit_test_main({"--run_test=suite2"});
}
}
See it Live On Coliru
The function relay_unit_test_main is really nothing more than a convenience wrapper around unit_test_main that avoids meddling with argv[] manually:
static bool init_function() { return true; }
static int relay_unit_test_main(std::vector<std::string> args)
{
std::vector<char const*> c_args;
c_args.push_back("fake_program_name");
std::transform(args.begin(), args.end(), std::back_inserter(c_args), std::mem_fn(&std::string::data));
c_args.push_back(nullptr);
return unit_test_main( &init_function, c_args.size()-1, const_cast<char**>(c_args.data()) );
}
This actually spawns a child process - and even tries to usefully combine the exit code information. Having a separate process prevents the problems that you'd get from using code that wasn't designed for multi-threaded use on different threads.
One caveat remains: if your program does static initializations before entry of main(), and these use external resources (like, log files, e.g.) there might be conflicts. See
man fork(3)
Does Boost Log support process forking? for an example of a lib that has potential issues with fork()
static int
MyReplacementExit(ClientData unused, Tcl_Interp *interp, int argc, const char *argv[])
{
// Tcl_DeleteInterp(interp);
// Tcl_Finalize();
return TCL_OK;
}
int main() {
Tcl_Interp *interp = Tcl_CreateInterp();
Tcl_CreateCommand(interp, "exit", MyReplacementExit, NULL, NULL);
Tcl_Eval(interp, "exit ; puts 11111111");
std::cout << "22222222222" << std::endl;
return 0;
}
I need to handle exit command evaluation of tcl interpreter. By default it tries to delete itself and also calls std::exit which closes whole program.It is not what I want so I am trying to replace it by custom proc. I dont need to delete interpreter in exit handler proc(I can do it later), only need it to not continue evaluating commands after exit command.
In this code I need to change MyReplacementExit proc somehow, so 11111111 doesn't be printed but
22222222222 does printed.
It can be achieved by returning TCL_ERROR from MyReplacementExit proc, but then I can't distinguish other error situations from this.
Make your replacement for exit delete the interpreter (which stops further commands from being executed, but doesn't actually immediately delete the data structure as it is still in use) and, important, wrap the call to Tcl_Eval with calls to Tcl_Preserve and Tcl_Release. Don't call Tcl_Finalize if you can possibly avoid it; that is for when you're about to unload the Tcl library from memory and can be quite tricky (it's easier to just quit the process, frankly).
Here's how to do it with your code (adapted):
static int
MyReplacementExit(ClientData unused, Tcl_Interp *interp, int argc, const char *argv[])
{
Tcl_DeleteInterp(interp); // <------------------
return TCL_OK;
}
int main() {
Tcl_Interp *interp = Tcl_CreateInterp();
Tcl_CreateCommand(interp, "exit", MyReplacementExit, NULL, NULL);
Tcl_Preserve(interp); // <------------------
Tcl_Eval(interp, "exit ; puts 11111111");
Tcl_Release(interp); // <------------------
std::cout << "22222222222" << std::endl;
return 0;
}
Be aware that you should not access the interpreter at all after the Tcl_Release as it might've been destroyed (as in, the memory released and scribbled over with random junk) at that point. If you need to retrieve results and use them (e.g., printing them out) do so beforehand.
Note that in this specific case, you don't need the preserve/release pair; your code isn't actually touching the interpreter after the Tcl_Eval (which does its own preserve/release internally).
If you don't want the interpreter to terminate, that's much trickier. The cleanest way in 8.4 is probably to throw a custom exception code (i.e., anything greater than TCL_CONTINUE) but there's no guarantee that it will work for arbitrary code as Tcl's catch command can still trap it. If you're really in that situation, it's actually easier to create an interpreter, run the arbitrary code in the sub-interp, and tear it down at the end of the script; you can then drop that interpreter without losing much context. Indeed, you could do:
Tcl_Preserve(interp);
if (Tcl_Eval(interp, theScriptToEval) != TCL_OK)
// Handle unexpected errors here
if (!Tcl_InterpDeleted(interp))
Tcl_DeleteInterp(interp);
Tcl_Release(interp);
Yes, this will mean you want to keep the amount of work you do to set up the interpreter fairly small; you probably won't want to try to call this every millisecond on an interrupt…
I'm trying to make a simple program that takes a user command, executes a function, then returns to the original function so the user can enter another command, much like windows command prompt. Upon browsing the similar questions I read that returning to main is not good programming so I want to ask:
How can I make a function that has access to the other functions but the other functions can return to once they finish their process?
After a function returns, control is returned to the calling function.
Example:
#include <iostream>
int other_function(){
std::cout << "In other_function...\n";
return 0;
}
int main(){
std::cout << "Calling other_function()...\n";
int ret_value = other_function();
std::cout << "Back in main. other_function returned "
<< ret_value << ".\n";
return 0;
}
This little program starts in main, calls other_function and then returns back to main. It prints, out the messages with std::cout as well. Try the program if you don't understand the concept.
Also, I personally see no problem with doing all of this in main, perhaps in a while-loop. What people mean (generally) when they say you shouldn't always return control to main is that you want to keep all of your functions short, preferably about as large as your screen. However, the main function is there for a reason, so use it (with care).
Just make sure that the functions have been declared (or #included), and your function should be able to call them all.
Good luck!
There's absolutely NO problems in returning to main() function.
In your case, you can do an algorithm in a way like this:
Step 1: Start Main() function
Step 2: Read the command from the user
Step 3: Compare the command by using if() and strcmp() function.
Step 3.a: Call the function for the command.
Step 4: Repeat through step 2.
Is there a line of code that will terminate the program?
Something like python's sys.exit()?
While you can call exit() (and may need to do so if your application encounters some fatal error), the cleanest way to exit a program is to return from main():
int main()
{
// do whatever your program does
} // function returns and exits program
When you call exit(), objects with automatic storage duration (local variables) are not destroyed before the program terminates, so you don't get proper cleanup. Those objects might need to clean up any resources they own, persist any pending state changes, terminate any running threads, or perform other actions in order for the program to terminate cleanly.
#include <cstdlib>
...
exit( exit_code );
There are several ways to cause your program to terminate. Which one is appropriate depends on why you want your program to terminate. The vast majority of the time it should be by executing a return statement in your main function. As in the following.
int main()
{
f();
return 0;
}
As others have identified this allows all your stack variables to be properly destructed so as to clean up properly. This is very important.
If you have detected an error somewhere deep in your code and you need to exit out you should throw an exception to return to the main function. As in the following.
struct stop_now_t { };
void f()
{
// ...
if (some_condition())
throw stop_now_t();
// ...
}
int main()
{
try {
f();
} catch (stop_now_t& stop) {
return 1;
}
return 0;
}
This causes the stack to be unwound an all your stack variables to be destructed. Still very important. Note that it is appropriate to indicate failure with a non-zero return value.
If in the unlikely case that your program detects a condition that indicates it is no longer safe to execute any more statements then you should use std::abort(). This will bring your program to a sudden stop with no further processing. std::exit() is similar but may call atexit handlers which could be bad if your program is sufficiently borked.
Yes! exit(). It's in <cstdlib>.
Allowing the execution flow to leave main by returning a value or allowing execution to reach the end of the function is the way a program should terminate except under unrecoverable circumstances. Returning a value is optional in C++, but I typically prefer to return EXIT_SUCCESS found in cstdlib (a platform-specific value that indicates the program executed successfully).
#include <cstdlib>
int main(int argc, char *argv[]) {
...
return EXIT_SUCCESS;
}
If, however, your program reaches an unrecoverable state, it should throw an exception. It's important to realise the implications of doing so, however. There are no widely-accepted best practices for deciding what should or should not be an exception, but there are some general rules you need to be aware of.
For example, throwing an exception from a destructor is nearly always a terrible idea because the object being destroyed might have been destroyed because an exception had already been thrown. If a second exception is thrown, terminate is called and your program will halt without any further clean-up having been performed. You can use uncaught_exception to determine if it's safe, but it's generally better practice to never allow exceptions to leave a destructor.
While it's generally always possible for functions you call but didn't write to throw exceptions (for example, new will throw std::bad_alloc if it can't allocate enough memory), it's often difficult for beginner programmers to keep track of or even know about all of the special rules surrounding exceptions in C++. For this reason, I recommend only using them in situations where there's no sensible way for your program to continue execution.
#include <stdexcept>
#include <cstdlib>
#include <iostream>
int foo(int i) {
if (i != 5) {
throw std::runtime_error("foo: i is not 5!");
}
return i * 2;
}
int main(int argc, char *argv[]) {
try {
foo(3);
}
catch (const std::exception &e) {
std::cout << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
exit is a hold-over from C and may result in objects with automatic storage to not be cleaned up properly. abort and terminate effectively causes the program to commit suicide and definitely won't clean up resources.
Whatever you do, don't use exceptions, exit, or abort/terminate as a crutch to get around writing a properly structured program. Save them for exceptional situations.
if you are in the main you can do:
return 0;
or
exit(exit_code);
The exit code depends of the semantic of your code. 1 is error 0 e a normal exit.
In some other function of your program:
exit(exit_code)
will exit the program.
This SO post provides an answer as well as explanation why not to use exit(). Worth a read.
In short, you should return 0 in main(), as it will run all of the destructors and do object cleanup. Throwing would also work if you are exiting from an error.
In main(), there is also:
return 0;
#include <cstdlib>
...
/*wherever you want it to end, e.g. in an if-statement:*/
if (T == 0)
{
exit(0);
}
throw back to main which should return EXIT_FAILURE,
or std::terminate() if corrupted.
(from Martin York's comment)
else if(Decision >= 3)
{
exit(0);
}
exit(0); // at the end of main function before closing curly braces
simple enough..
exit ( 0 );
}//end of function
Make sure there is a space on both sides of the 0. Without spaces, the program will not stop.