Hello,
I have a class that I developed using exceptions, but every time I call a function and it generates an exception, the program appears to hang. Closer investigation shows that the throw command has a long list of calls that eventually calls exit().
throw command -> __cxa_throw() -> std::terminate() -> __cxabiv1::__terminate() -> abort() -> _exit()
I have used this same method numerous times before so I'm pretty confident that the problem is not in the implementation, but I'm struggling with locating the root cause. Any suggestions?
Source of the exception (_connectTcp()):
status = nxd_tcp_client_socket_connect(
socket_ptr,
&server_addr,
port,
wait_option);
if( status != NX_SUCCESS)
{
throw ERRORS::TCP_SOCKET_BIND_ERROR;
}
Try/Catch Block
try
{
_connectTcp( socket_ptr, ip_addr, port, connect_wait);
}
catch( ERRORS err)
{
error = err;
}
Copy of stack:
_exit() at _exit.c:19 0x60040b36
abort() at 0x60034da4
__cxxabiv1::__terminate() at 0x60035604
std::terminate() at 0x60035612
__cxa_throw() at 0x60035752
RtController_Ethernet::_connectTcp() at RTController_Ethernet.cpp:1,063 0x6000945c
Solved! Go to Solution.
Newlib nano is a small footprint C/C++ library. IT does not contain some of the main language features, to make it much smaller (i.e. no C++ exceptions). See
Shrink Your MCU code size with GCC ARM Embedded 4.7 - Embedded blog - System - Arm Community
You said you used Newlib and so I didn't say anything. If you had, I could have told you that 'nano does not support C++ exceptions!
To see why: Using the sample above, compiled with Newlib, the application is 263k code and 8k data (approx). Using newlibnano (with no C++ exception support) is 163k and 6k - that is, the exception handling code adds 100k of code and 2k of data - it is a really really expensive feature.
Lesson - it is important to be accurate in your problem description...
While I do not completely understand the issue, I was able to resolve it by changing the NewLib libraries.
Per the explanation on the differences between the NewLib and NewLibNano (https://community.nxp.com/thread/389086 ) and the explanation of the the different types of hosting (What are none, nohost and semihost libraries? ), I incorrectly stated that I was using the NewLib library. In fact, I was using the NewLibNano library. I changed over to the NewLib libraries for both my C and C++ compiler settings and set the linker to use NewLib (nohost). Now, the exceptions are again being caught and not going straight to terminate.
My question is, why would this have fixed the problem and why did it suddenly go from working to not working?
Newlib nano is a small footprint C/C++ library. IT does not contain some of the main language features, to make it much smaller (i.e. no C++ exceptions). See
Shrink Your MCU code size with GCC ARM Embedded 4.7 - Embedded blog - System - Arm Community
You said you used Newlib and so I didn't say anything. If you had, I could have told you that 'nano does not support C++ exceptions!
To see why: Using the sample above, compiled with Newlib, the application is 263k code and 8k data (approx). Using newlibnano (with no C++ exception support) is 163k and 6k - that is, the exception handling code adds 100k of code and 2k of data - it is a really really expensive feature.
Lesson - it is important to be accurate in your problem description...
NewLib-Nano is compiled *without* exceptions support.
see as well https://community.nxp.com/thread/537067
Are you sure that connectTcp is called only there, and not from somewhere else that is not caught? Alternatively have you tries a catch-all handler?
Hello,
Yes, this private function (_connectTcp) was written specifically to support the public function (connectTcpSocket) and is only accessible inside the class. (I also can generate this issue when I step through the code from the connectTcpSocket function.) I did try a "catch (...)", but the exception still went straight to the _exit() chain.
Which c library are you using? Newlib or nano?
Does the answer to this help?
Hello,
I tried the fix as suggested and I am still failing on all exceptions.
Per the suggestion, I replaced the exdata.ldt and can confirm that the specified changes were made to the file. I then did a clean/build and confirmed that the <ProjectName>_Debug.ld has the correct change. Programming the board and inserting the early catch into my main, I immediately fail and exit the program.
Can you provide a simple project that demonstrates the problem. When I get a chance, I’ll take a look (probably this time tomorrow).
OK, I don't have a MiMXRT1062, so I just used a plain old LPC1768 - and exceptions worked.
I created a new C++ project, changed the miscellaneous option to allow exceptions (-fexceptions) and created a simple exception test, based on your code (I couldn't get cout to print!)
main(){
char *what;
try {
throw std::runtime_error("Exceptions are being handled normally.");
} catch (std::runtime_error &e) {
what = (char*) e.what();
}
return 0;
}
I set the breakpoint on the return and ran the code, and 'what' contained the correct string.
Can you try something similar?
Hello,
If I start a new project, then the exceptions work. However, sample I provided is based on my existing application and is fairly large and complex. At one point the exceptions were working, but now they just terminate the program. I'm hoping that you can help me determine what is wrong.