Interrupting a C function execution and getting back to C++ caller
I currently have a problem implementing the following scenario using the following configuration: GCC 3.4, Linux.
I have written a tool (in C++) which loads a shared library (written in C). This library has a bug which I cannot influence to fix. The problem is that it reads some input and writes decoded output. Sometimes if the input is wrong, this library without doing any checks starts decoding of the following memory regions. That causes a segfault.
Initially my idea was to put the input into the paged memory (linux mmap-syscall) and protect (mprotect) the last page, against access. By installing an own SIGSEGV handler my C++-App can throw an exception (when compiled with GCC flag -fnon-call-exceptions). This exception will interrupt the C lib's reading. I known that this lib does not allocate any memory (or other resources), which might be lost during stack-unwinding. The whole scenario worked fine in my unit tests, where everything was a single C++ app. But now when the C code from the lib is called my app just terminates... Do I need to rebuild this C-SO with -fnon-call-exceptions flag as well? I can't compile this lib, but only re-link it, since I have access to obj files only.
Here is the picture of the execution environment:
+----开发者_高级运维--------C++ APP----------+
| |
| Install SIGSEGV handler |
| code calling C SO functions |
| |
| +----------C SO Functions------------+
| | execute producing SIGSEGV |
| +------------------------------------+
| |
| SIGSEGV Handler called |
| => throw Exception |
| to stop execution of |
| C function |
+-----------------------------+
Other suggestions are welcome.
Many thanks,
Ovanes
P.S. I see some suggestions and critics but they are all not an optin. Here is why: I only have one interface, where I can link to the library. The library is used to decode data structures. The problem is that if I have an array with the length -1 the library starts to decode the array of length 0xffffff (on a 32 bit system). Waiting until the lib crashes in a separate process is not an option in my opinion. First of all decoding will take a considarable ammount of time on one hand and will produce lots of trash on the other. Since my tool needs to show the decoded output reliably to the users. And they still need to be able to understand the traces.
I don't see the point here to work around a SIGSEGV. First of all, the library reads data and writes it to the file handle which I passed before. I can configure how to write to that handle (buffered or not). Furthermore, I know exactly that it does not allocate any heap data or resources. And finally, it tries to access memory which my app protected to avoid such errors. From the user's perspective I can't tell to someone: Sorry the binary trace was only half decodable, because some data was inconsistent. I know that this data was inconstent and I exactly know how to deal with this inconsistency. So I can gracefully recover. I think I will try to use sigsetjmp/siglongjmp POSIX functions and hope they will do better as exception. Indeed either setjmp/longjmp or sigsetjmp/siglongjmp are used to implement exceptions.
Yes, I debugged my application and see that the call stack is valid.
Unfortunately I don't have an answer for the problem as stated - have you tried running your application under a debugger, to see where exactly it terminates?
However, an alternative approach which came to my mind would be to put the usage of the faulty library into a separate program, launch it from your app and pass it the data via a pipe.
This might be stupid question, but have to examined core file? Or run your application in debugger?
Ok Guys,
I did it with sigsetjmp/siglongjmp. Works like a charm. I can jump over the function into the stack of the caller function and do error handling there.
Thanks for all the suggestions.
Best Regards,
Ovanes
精彩评论