I am using a Graphics Library called Irrlicht
at some point i have to write this code
if(!device){
//error code here`
}
i am not in the main function but want to close the application when this error happens
please keep in mind that I am a beginner so this question might sound dumb
i see some people do this:
int main(){
if(!device){
return 1;
}
return 0;
}
i am not in the main function and want to exit the application outside of the main function
The following example give you an idea about some of the possibilities.
You can simply copy and paste it and play around with it. Simply use only one line of the "termination actions" like throw or exit. If you don't have the try catch block in the main function, your application will also terminate because the exception will not be caught.
struct DeviceNotAvailable {};
struct SomeOtherError{};
void func()
{
void* device = nullptr; // only for debug
if (!device)
{
// use only ONE of the following lines:
throw( DeviceNotAvailable{} );
//throw( SomeOtherError{} );
//abort();
//exit(-1);
}
}
int main()
{
// if you remove the try and catch, your app will terminate if you
// throw somewhere
try
{
func();
}
catch(DeviceNotAvailable)
{
std::cerr << "No device available" << std::endl;
}
catch(SomeOtherError)
{
std::cerr << "Some other error" << std::endl;
}
std::cout << "normal termination" << std::endl;
}
Related
After declaring an object in my main and running its function in a separate thread, my program crashes.
I have read other question on SO but due to my lack of knowledge in multithreading, I cannot understand what is my specific problem.
Here is my class called UART (without header files and only showing the required cpp declaration):
void UART::run()
{
while(true)
{
_letter = _serial.read();
if (_letter == "!")
{
_line = _serial.readline();
_words.clear();
std::istringstream f(_line);
std::string s;
//std::cout << _letter << std::endl;
while (getline(f,s,'\t'))
{
_words.push_back(s);
}
this->fillVars();
}
}
}
void UART::fillVars()
{
if (_words[0] == "s")
{
_effort[0] = std::stoi(_words[1]);
_effort[1] = std::stoi(_words[2]);
}
else if (_words[0] == "e")
{
this->convertToMeters();
}
}
void UART::convertToMeters()
{
std::cout << _position[0];
_position[0] = std::stod(_words[1]); // / _tick_meters;
_position[1] = std::stod(_words[2]) / _tick_meters;
}
double UART::getPosition(std::string wheel)
{
if (wheel == "LEFT") return _position[0];
else return _position[1];
}
And my main cpp looks like this:
int main(int argc, char** argv)
{
ros::init(argc, argv, "joint_node");
std::string port("/dev/ttyACM0");
unsigned long baud = 115200;
try
{
serial::Serial my_serial(port, baud, serial::Timeout::simpleTimeout(1000));
if(my_serial.isOpen()) ROS_INFO("Serial is %s", "open");
genius::UART uart(my_serial, 380);
std::thread uart_run(&genius::UART::run, uart);
std::cout << uart.getPosition("LEFT") <<std::endl;
} catch (std::exception &e)
{
std::cerr << "Unhandled Exception: " << e.what() << std::endl;
}
return 0;
}
My understanding is that after creating an object uart, I want to run its function run() in a separate thread as I want its values to be updated with no interruption on a background. So whenever I access its values like using its function uart.getPosition("LEFT") I will get the last up-to date data. I guess I do not need .join() this thread as I do not want to wait for it as it never ends.
But for some reason after calling the uart.getPosition("LEFT") my program crashes and also function getPosition() never gets executed and I always get value of 0.
I am trying to run some function in asynchronous manner. For this purpose I wrote class called Core where I use std::async to run function in different thread and std::shared_future<int> to wait for this thread and possibly to get future result. This is code of test program:
#include <iostream>
#include <future>
class Core : public std::enable_shared_from_this<Core>
{
public:
Core()
: isRunning_(false) {
};
~Core() {
isRunning_ = false;
if (f_.valid())
{
f_.wait();
std::cout << "Result is: " << f_.get() << std::endl;
}
};
void Start() {
isRunning_ = true;
auto self(shared_from_this());
f_ = std::async(std::launch::async, [self, this]() {
try {
while (true) {
if (!isRunning_)
break;
std::cout << "Boom" << std::endl; // Error occurs here
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
catch (const std::exception& e) {
std::cerr << "Loop error:" << e.what();
}
return 999;
});
}
private:
std::shared_future<int> f_;
std::atomic<bool> isRunning_;
};
int main()
{
try {
std::shared_ptr<Core> load(new Core);
load->Start();
throw std::runtime_error("Generate error"); // Added in order to generate error
}
catch (const std::exception& e) {
std::cout << "Error occurred: " << e.what();
}
return 0;
}
Each time when I start this program it crashes at this line:
std::cout << "Boom" << std::endl; // Error occurs here
with this error:
That is debugger error and call stack which I managed to get during debugging:
Looks like Core destructor function doesn't call at all. Why is it happens? weird!!!
Could you tell me where is my mistake? Thanks.
When main thread returns from main() it starts tearing down the environment before terminating the whole process. All this while background thread is accessing objects there are being destroyed or have been destroyed already.
I am not sure what you are triying to achieve, but you are doing something wrong:
Your lambda should execute some work and return immediately after it is done e.g. you should never loop forever.
Your main thread should wait for your future to complete by calling std::future<T>::get().
I had this funny idea last night, to trap hardware exceptions and throw a C++ exception instead. Thought that might be useful for things like FPU exceptions, which normally either crash, or silently return NaN and then cause unexpected behaviour. A C++ exception would be far more desirable here.
So I've been hacking all morning and finally got it to work. Well, almost. The compiler still doesn't realize that arithmetic operations can now throw C++ exceptions, and will silently discard the try/catch block around it. It does work when the exception occurs in a function.
void throw_exception()
{
throw std::runtime_error("Division by zero!");
}
__attribute__((noinline))
void try_div0()
{
cout << 1 / 0 << endl;
}
int main()
{
// this class traps a hardware exception (division by zero, in this case) and calls the supplied lambda function.
// uh, no, you probably don't want to see the assembly code behind this...
exception_wrapper div0_exc { 0, [] (exception_frame* frame, bool)
{
if (frame->address.segment != get_cs()) return false; // only handle exceptions that occured in our own code
frame->stack.offset -= 4; // sub <fault esp>, 4;
auto* stack = reinterpret_cast<std::uintptr_t *>(frame->stack.offset); // get <fault esp>
*stack = frame->address.offset; // mov [<fault esp>], <fault address>;
frame->address.offset = reinterpret_cast<std::uintptr_t>(throw_exception); // set return address to throw_exception()
return true; // exception handled!
} };
try
{
// cout << 1 / 0 << endl; // this throws, as expected, but calls std::terminate().
try_div0(); // this exception is caught.
}
catch (std::exception& e)
{
cout << "oops: " << e.what() << endl;
}
}
I realize this is an unusual question... but is there any way I could make this work? Some way to tell gcc that exceptions can occur anywhere?
I'm compiling with djgpp which (I believe) uses DWARF exception handling.
edit: I just found gcc flags -fnon-call-exceptions and -fasynchronous-unwind-tables, which appear to be what I'm looking for. But it still doesn't work...
edit: Now using the previously mentioned gcc flags, it does catch when the exception occurs in between two function calls:
inline void nop() { asm(""); }
// or { cout << flush; } or something. empty function does not work.
int main()
{
/* ... */
try
{
nop();
cout << 1 / 0 << endl;
nop();
}
/* ... */
}
edit: Nested try/catch blocks have the same effect, no exception is caught unless the trapped instruction is preceded by a function call.
inline void nop() { asm(""); }
void try_div(int i)
{
try
{
// this works, catches exception in try_div(0).
nop();
cout << 1 / i << endl;
try_div(i - 1);
// without the first nop(), calls std::terminate()
//cout << 1 / i << endl;
//try_div(i - 1);
// reverse order, also terminates.
//if (i != 0) try_div(i - 1);
//cout << 1 / i << endl;
//nop();
}
catch (std::exception& e)
{
cout << "caught in try_div(" << i << "): " << e.what() << endl;
}
}
int main()
{
/* ... */
try
{
try_div(4);
}
catch (std::exception& e)
{
cout << "caught in main(): " << e.what() << endl;
}
}
edit: I have submitted this as a possible bug in gcc, and reduced my code to a simple test case.
It's been a while, but I finally figured it out... The throwing function needs to be marked as having a signal frame.
[[gnu::no_caller_saved_registers]]
void throw_exception()
{
asm(".cfi_signal_frame");
throw std::runtime_error("Division by zero!");
}
I'm trying to use ROS_INFO_STREAM inside an imbricated try...catch but I only have the top-level output
Here's a minimal bunch of code:
void failure()
{
try
{
// throw std::length_error
std::string("abc").substr(10);
}
catch (...)
{
ROS_ERROR_STREAM("ROS failure()"); // print OK
std::cout << "cout failure()" << std::endl; // print OK
throw; // re-throw the exception
}
}
int main()
{
try
{
ROS_ERROR_STREAM("ROS calling"); // print OK
failure(); // will throw
}
catch (...)
{
ROS_ERROR_STREAM("ROS call function"); // <-- NO print
std::cout << "cout call function" << std::endl; // print OK
}
return 0;
}
output:
ROS calling
ROS failure()
cout failure()
cout call function
My guess would be that ROS_ERROR_STREAM looks buffered but as an error output it shouldn't be.
I'm running ROS Groovy
All the macros in rosconsole stop working when ros::shutdown() has been called somewhere in the ROS node.
I can imagine that something like that happens to you: the catch block in the main is probably reached after an error which calls automatically the ros::shutdown() function.
If you would like to maintain the same output format like the one provided by ROS macros, you can use a simple code like this one, but forget to get the code highlighted with colors or other stuff:
std::cout << "[ INFO] [" << ros::Time::now() << "]: main catch" << std::endl;
For ROS_* logging statements to work you have to have either explicitly called ros::init(...) and ros::start(...) beforehand, or as is more common, call ros::init and initialize a ros::NodeHandle. The latter will call ros::start for you.
However, when the last NodeHandle goes out of scope it will call ros::shutdown() and after this point, again you won't be able to use any of the logging macros.
I have used custom terminate handler which works fine if I call throw with a type or explicitly call terminate(), but if I use rethow i.e throw; , the custom terminate handler is not called, only default terminate handler is called causing the program to abort. Code confirms to C++03. Could anyone help me to find out the problem ? Thank you in advance
#include <iostream>
#include <exception>
using namespace std;
void myunexpected() {
cerr << "CUSTOM unexpected handler called ------ \n";
throw 0; // throws int (in exception-specification)
}
void myterminate () {
cerr << "CUSTOM terminate handler called ------ \n";
//abort(); // forces abnormal termination
exit(0);
}
void myfunction() throw (int) {
throw 'x'; // throws char (not in exception-specification)
}
int main(void) {
set_unexpected(myunexpected);
set_terminate(myterminate);
int a = 1;
try{
try {
myfunction();
}
catch (int) {
cerr << "caught int\n";
throw string("sree");
}
catch (...) { cerr << "caught some other exception type\n"; }
}
catch (string& s)
{
cerr << a << "caught STRING " << s << endl;
//throw 0; //ok --> implicitly calls terminate()-->myterminate
//terminate(); //ok --> explicitly calls terminate()-->myterminate
throw; //--------- Calls default throw Why ???
}
return 0;
}
OUTPUT
CUSTOM unexpected handler called ------
caught int
1caught STRING sree
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
--------------------------------
Process exited after 8.238 seconds with return value 255
Press any key to continue . . .