Catching/Handling exceptions thrown in AngelScript functions - c++

I'm playing around with AngelScript, and one thing I can't seem to wrap my head around is how to catch exceptions thrown from C++ but called from AngelScript. Here's what I've got so far:
// test.as
void main()
{
print("Calling throwSomething...");
throwSomething();
print("Call finished");
}
void print(string) and void throwSomething() are two functions registered to the engine, source below. As per the AngelScript docs:
Application functions and class methods registered with the script engine are allowed to throw C++ exceptions. The virtual machine will automatically catch any C++ exception, abort the script execution, and return control to the application.
Here's the example code provided for handling exceptions:
asIScriptContext *ctx = engine->CreateContext();
ctx->Prepare(engine->GetModule("test")->GetFunctionByName("func"));
int r = ctx->Execute();
if( r == asEXECUTION_EXCEPTION )
{
string err = ctx->GetExceptionString();
if( err == "Caught an exception from the application" )
{
// An application function threw an exception while being invoked from the script
...
}
}
I pretty much verbatim copied this code into my editor and tried to run it. Unfortunately, even though I wrapped the call to Execute in a try-catch block, I still get this output:
(AngelScript) Calling throwSomething...
(C++) throwSomething Entered...
libc++abi.dylib: terminating with uncaught exception of type std::runtime_error: Assert(1 == 0) failed, line 68
Abort trap: 6
For completeness' sake, here's the code for throwSomething and print:
void throwSomething()
{
cout << "(C++) throwSomething Entered...\n";
Assert(1 == 0); // will throw an exception
cout << "(C++) throwSomething Exiting...\n";
}
void print(string s)
{
cout << "(AngelScript) " << s << "\n";
}
So, I'm feeling a little stuck. I tried registering an exception translation function (see linked doc) in hopes that would help, but I still got the same results. From looking at Xcode's debugger, the exception appears to happen in the main thread-- so I'm unsure why neither my code or the code in the AngelScript library itself catches the exception.
So, I guess my question is: 1) how can I either catch the exception within my program, or 2) If I can't catch it from within the program, how can I otherwise handle it without the program crashing?
I'm running this on a ~2015 MacBook Pro running MacOS 10.14.6 and AngelScript version 2.33.0, if that's relevant.

Related

Why I get First-chance exception if no one calls the function?

Suddenly my code started to throws an exception First-chance exception at 0x7731c41f in VideoPlayer.exe: Microsoft C++ exception: GenICam::RuntimeException at memory location 0x0018f5dc.. I could not find where exactly it throws from, so I commented all in main function and everything outside the main. I started to uncomment blocks of code one by one whilst the code in main remains commented. While doing it I noticed that there is function A that when it is commented there is no exception, but when it's uncommented it throws the exception above.
I don't understand how it can cause exeception if it's not called ( I placed breakpoint in it and code in main is commented)?
You function will be used during the static initialization.
Take the following example:
#include <iostream>
bool static_func()
{
std::cout << "Before main" << std::endl;
return true;
}
static const bool b = static_func();
int main()
{
std::cout << "We are main" << std::endl;
return 0;
}
Since you only see a first chance exception it will be caught and handled. I have seen such constructs in abstract factories for example, where the factory configures itself.
The reason why your breakpoint is not hit must be something else.
In VS, Debug menu, Exceptions... check the throw column for the matching type. Then start debugging and it will stop exactly where throw happens. And you can look around why.

How to cause C++ throw to dump core if the exception would be handled by a particular catch block

Is there a way to cause a throw in C++ to dump core at the throw site if the thrown exception would be handled by a certain catch block? I would like something similar to what happens with g++ when an exception reaches the top level.
For example, I would like something like this:
try {
bar();
try {
foo();
} catch(...) {
# pragma dump_at_throw_site
}
} catch(...) {
std::cerr << "There was a problem" << std::endl;
}
This way, if any exception thrown from foo() or its callee's that reaches the call-site of foo() would cause a core dump at the throw site so one can see who threw the exception that made it to the to this level.
On the other hand, exceptions thrown by bar() would be handled normally.
Yes,it can in Windows. I don't know Linux, suppose it can also.
We can register a Exception Handler function to response the throw before the catch
Here is the code example:
#include <iostream>
#include "windows.h"
#define CALL_FIRST 1
LONG WINAPI
VectoredHandler(
struct _EXCEPTION_POINTERS *ExceptionInfo
)
{
UNREFERENCED_PARAMETER(ExceptionInfo);
std::cout <<"VectoredHandler"<<std::endl;
return EXCEPTION_CONTINUE_SEARCH;
}
int main()
{
PVOID handler;
handler = AddVectoredExceptionHandler(CALL_FIRST,VectoredHandler);
try {
throw 1;
}catch(...)
{
std::cout <<"catch (...)"<< std::endl;
}
RemoveVectoredExceptionHandler(handler);
std::cout << "end of main"<<std::endl;
return 0;
}
The outputs of code are:
VectoredHandler
catch (...)
end of main
So,you can dump core int the function VectoredHandler.
The VectoredHandler is called after the debugger gets a first chance notification, but before the system begins unwinding the stack.
And if your purpose is just to debug the problem issue, then you can rely on the debugger feature to handle the first chance exception, don't need dump the application.
For your information, you may need know What is a First Chance Exception? in windows to understand how windows dispatch the exception.

What could be overriding the return code from main()?

I have a rather odd occurrence happening that I haven't been able to nut out yet.
I have test case that is supposed to catch errors and return the appropriate error code from main, but /sometimes/ on test runs the program returns 0 even when the error code is non zero.
The exception class thrown is:
class exit_request {
public:
explicit exit_request(int code = 0) : m_code(code) {}
int code() const { return m_code; }
private:
int m_code;
};
The test case code is:
int main(int argc, char* argv[])
{
try {
// Do some test case stuff
// Eventually, due to the supplied command line arguments,
// we expect an exit_request() to be thrown from within
// library code.
}
catch (exit_request& exp) {
std::cout << "Exit Request:" << exp.code() << std::endl;
return exp.code();
}
catch (std::exception& err) {
std::cout << "Error: " << err.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
In many runs of this test case, everything works as expected: The exit_request() exception is thrown, caught, exp.code() is printed (its value is 2), and the return code from the process is 2.
However, very occasionally, the return code from the process is 0 (i.e. no failure), even though exp.code() is printed as 2.
Can anyone help explain a situation in which this can occur? i.e. the return value from main is changed from non-zero to zero before the process exits?
This is occurring on Windows 7 (x64), with MSVC++ 2010 Express, building a x86 (32-bit) application. I have not seen this odd failure on any of our other Windows or Linux platforms, or compilers, but that doesn't necessarily mean it couldn't happen in those environments.
If you have any atexit handlers that call exit(0), or any static-storage-duration objects whose destructors do that, it might explain what you're seeing. They get executed after your return statement. It's undefined behavior, which could explain why you only see it happen sometimes.
Maybe you are not throwing the exception correctly...
I mean that from the function called or processing done in try block, you are throwing exception of some other type.
Try to write a default catch block for that.

Function-body exceptions [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Difference between try-catch syntax for function
What is the difference in the utility and behavior of these try-catch blocks? When would I prefer one form over the other?
int f() {
try {
...
} catch(...) {
...
}
}
int f() try {
...
} catch (...) {
...
}
If the entire body must go into the exception block, I tend to prefer the 2nd form as it's easier to read (e.g. one less indentation level).
However, the main place where this makes a difference is in constructors. Consider:
Foo::Foo ()
try : member_with_throwing_constructor(initial_value)
{
}
catch ( ... )
{
// will process exceptions thrown by `member_with_throwing_constructor`
// this will be added by the compiler if you
// don't finish by a `throw ...` statement.
throw;
}
and
Foo::Foo ()
: member_with_throwing_constructor(initial_value)
{
try
{
}
catch ( ... )
{
// does not catch exceptions thrown in constructor
// of `member_with_throwing_constructor`.
}
// can keep processing if `catch` handler does not `return` or `throw`.
}
These two code snippets have radically different behavior. The first one will catch exceptions raised in data member constructors (usually through the initializer list, but default constructors apply too) and will automatically re-raise the exception because the instance could not be created safely. The second form does not cover data member initialization and allows you to choose whether to keep the object or not.
I also like to add a global try-catch in main() to help with debugging uncaught exceptions. The following snippet:
int main ( int, char ** )
try
{
// main program...
}
catch ( const std::exception& error )
{
std::cerr << "Uncaught exception: '" << error << "'." << std::endl;
return (EXIT_FAILURE);
}
catch ( ... )
{
std::cerr << "Uncaught exception of unknown type." << std::endl;
return (EXIT_FAILURE);
}
Some people will argue that not catching the exceptions allows the program to crash and you can get a core dump to help with debugging. While this may be useful in debug mode, as it can help the debugger point you to the exact line of code that raised the exception, I like to ship programs that don't crash, and I can show the user a message saying a bug report was submitted.
Function try-catch blocks are only useful in constructors, and even then, not very useful at all. It's best to just forget they exist.

C++ unhandled exceptions

Does C++ offer a way to 'show' something visual if an unhandled exception occurs?
What I want to do is to make something like assert(unhandled exception.msg()) if it actually happens (like in the following sample):
#include <stdexcept>
void foo() {
throw std::runtime_error("Message!");
}
int main() {
foo();
}
I expect this kind of code not to terminate immediately (because exception was unhandled), rather show custom assertion message (Message! actually).
Is that possible?
There's no way specified by the standard to actually display the message of the uncaught exception. However, on many platforms, it is possible anyway. On Windows, you can use SetUnhandledExceptionFilter and pull out the C++ exception information. With g++ (appropriate versions of anyway), the terminate handler can access the uncaught exception with code like:
void terminate_handler()
{
try { throw; }
catch(const std::exception& e) { log(e.what()); }
catch(...) {}
}
and indeed g++'s default terminate handler does something similar to this. You can set the terminate handler with set_terminate.
IN short, no there's no generic C++ way, but there are ways depending on your platform.
Microsoft Visual C++ allows you to hook unhandled C++ exceptions like this. This is standard STL behaviour.
You set a handler via a call to set_terminate. It's recommended that your handler do not very much work, and then terminate the program, but I don't see why you could not signal something via an assert - though you don't have access to the exception that caused the problem.
I think you would benefit from a catch-all statement as follows:
int main() {
try {
foo();
catch (...) {
// Do something with the unhandled exception.
}
}
If you are using Windows, a good library for handling unhandled exceptions and crashes is CrashRpt. If you want to do it manually you can also use the following I wrote in this answer.
If I'm reading your question correctly, you're asking if you can overload throw (changing its default behavior) so it does something user-defined. No, you can't.
Edit: since you're insistent :), here's a bad idea™:
#include <iostream>
#include <stdlib.h>
#include <windows.h>
void monkey() {
throw std::exception("poop!");
}
LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *lpTopLevelExceptionFilter) {
std::cout << "poop was thrown!" << std::endl;
return EXCEPTION_EXECUTE_HANDLER;
}
int main() {
SetUnhandledExceptionFilter(&MyUnhandledExceptionFilter);
monkey();
return 1;
}
Again, this is a very bad idea, and it's obviously platform-dependent, but it works.
Yes, its possible. Here you go:
#include <iostream>
#include <exception>
void foo()
{
throw std::exception("Message!");
}
int main()
{
try
{
foo();
}
catch (std::exception& e)
{
std::cout << "Got exception: " << e.what() << std::endl;
}
return 0;
}
The c++ standard is the terminate handler - as other have said
If you are after better traceablility for throws then this is what we do
We have a macro Throw that logs the file name and line number and message and then throws. It takes a printf style varargs message.
Throw(proj::FooException, "Fingle %s unable to process bar %d", fingle.c_str(), barNo);
I get a nice log message
Throw FooException from nargle.cpp:42 Fingle barf is unable to process bar 99
If you're really interested in what happened to cause your program to fail, you might benefit from examining the process image in a post-mortem debugger. The precise technique varies a bit from OS to OS, but the basic train is to first enable core dumping, and compile your program with debug symbols on. Once the program crashes, the operating system will copy its memory to disk, and you can then examine the state of the program at the time it crashed.