How to generate stack trace from SEH exception - c++

I am catching an exception using Win32 SEH:
try
{
// illegal operation that causes access violation
}
__except( seh_filter_func(GetExceptionInformation()) )
{
// abort
}
where the filter function looks like:
int seh_filter_func(EXCEPTION_POINTERS *xp)
{
// log EIP, other registers etc. to file
return 1;
}
This works so far and the value in xp->ContextRecord->Eip tells me which function caused the access violation (actually - ntdll.dll!RtlEnterCriticalSection , and the value for EDX tells me that this function was called with a bogus argument).
However, this function is called in many places, including from other WinAPI functions, so I still don't know which code is responsible for calling this function with the bogus argument.
Is there any code I can use to generate a trace of the chain of function calls leading up to where EIP is now, based on the info in EXCEPTION_POINTERS or otherwise? (Running the program under an external debugger isn't an option).
Just EIP values would be OK as I can look them up in the linker map and symbol tables, although if there is a way to automatically map them to symbol names that'd be even better.
I am using C++Builder 2006 for this project, although an MSVC++ solution might work anyway.

I think you can use Boost.Stacktrace for this:
#include <boost/stacktrace.hpp>
int seh_filter_func(EXCEPTION_POINTERS *xp)
{
const auto stack = to_string( boost::stacktrace::stacktrace() );
LOG( "%s", stack.c_str() );
return 1;
}

Related

Calling function within C++ classs not working

I have been working on this simply hobbyist OS, and I have decided to add some C++ support. Here is the simple script I wrote. When I compile it, I get this message:
cp.o: In function `caller':
test.cpp:(.text+0x3a): undefined reference to `__stack_chk_fail'
Here is the script:
class CPP {
public:
int a;
void test(void);
};
void CPP::test(void) {
// Code here
}
int caller() {
CPP caller;
caller.test();
return CPP.a;
}
Try it like this.
class CPP {
public:
int a;
void test(void);
};
void CPP::test(void) {
CPP::a = 4;
}
int caller() {
CPP caller;
caller.test();
return caller.a;
}
int main(){
int called = caller();
std::cout << called << std::endl;
return 0;
}
It seems to me that the linker you are using can't find the library containing a security function crashing the program upon detecting stack smashing. (It may be that the compiler doesn't include the function declaration for some reason? I am not familiar who actually defies this specific function.) Try compiling with -fno-stack-protector or equivalent.
What is the compiler used? A workaround might be defining the function as something like exit(1); or similar. That would produce the intended effect yet fix the problem for now.
I created a test program to show how this actually plays out. Test program:
int main(){
int a[50]; // To have the compiler manage the stack
return 0;
}
With only -O0 as the flag ghidra decompiles this to:
undefined8 main(void){
long in_FS_OFFSET;
if (*(long *)(in_FS_OFFSET + 0x28) != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return 0;
}
With -fno-stack-protector:
undefined8 main(void){
return 0;
}
The array was thrown out by ghidra in decompilation, but we see that the stack protection is missing if you use the flag. There are also some messed up parts of this in ghidra (e.g. int->undefined8), but this is standard in decompilation.
Consequences of using the flag
Compiling without stack protection is not good per se, but it shouldn't affect you in much. If you write some code (that the compiler shouts you about) you can create a buffer overflowable program, which should not be that big of an issue in my optinion.
Alternative
Alternatively have a look at this. They are talking about embedded systems, but the topic seems appropriate.
Why is the code there
Look up stack smashing, but to my knowledge I will try to explain. When the program enters a function (main in this case) it stores the location of the next instruction in the stack.
If you write an OS you probably know what the stack is, but for completeness: The stack is just some memory onto which you can push and off which you can pop data. You always pop the last pushed thing off the stack. C++ and other languages also use the stack as a way to store local variables. The stack is at the end of memory and when you push something, the new thing will be further forward rather than back, it fills up 'backwards'.
You can initialise buffers as a local variable e.g. char[20]. If you filled the buffer without checking the length you might overfill this, and overwrite things in the stack other than the buffer. The return address of the next instruction is in the stack as well. So if we have a program like this:
int test(){
int a;
char buffer[20];
int c;
// someCode;
}
Then the stack will look something like this at someCode:
[ Unused space, c, buffer[0], buffer[1] ..., buffer[19], a, Return Address, variables of calling function ]
Now if I filled the buffer without checking the length I can overwrite a (which is a problem as I can modify how the program runs) or even the return address (which is a major flaw as I might be able to execute malicious shellcode, by injecting it into the buffer). To avoid this compilers insert a 'stack cookie' between a and the return address. If that variable is changed then the program should terminate before calling return, and that is what __stack_chk_fail() is for. It seems that it is defined in some library as well so you might not be able use this, despite technically the compiler being the one that uses this.

Replacement of dump_stack() in freertos

I have FreeRTOS running on ARM processor and I don't have dump_stack() available to me... I am trying to check the call-chain and badly missing dump_stack()... I was googling a bit, and found something close to what i was looking for, using GCC(/GDB) _Unwind_Backtrace() utility but it only prints the address of stack_frame. It doesn't provide mapping to meaningful symbol (like function names). Any help is really appreciated.
#include <stdio.h>
#include <unwind.h>
#include <stdint.h>
static _Unwind_Reason_Code unwind_backtrace_callback(struct _Unwind_Context* context, void* arg)
{
uintptr_t pc = _Unwind_GetIP(context);
if (pc) {
printf("unwind got pc ...0x%x\n", pc);
}
return _URC_NO_REASON;
}
ssize_t unwind_backtrace()
{
_Unwind_Reason_Code rc = _Unwind_Backtrace(unwind_backtrace_callback, 0);
return rc == _URC_END_OF_STACK ? 0 : -1;
}
void func_1()
{
int ret = unwind_backtrace();
printf("unwind_backtrace return ...%d\n", ret);
}
void func_2()
{
func_1();
}
int main()
{
func_2();
return 0;
}
Result:
unwind got pc ...0x40076b
unwind got pc ...0x400796
unwind got pc ...0x4007bd
unwind got pc ...0x400819
unwind got pc ...0x67314b15
unwind got pc ...0x400649
unwind_backtrace return ...0
All the IDEs I use (and I use a lot) show me the stack trace in a window - but only for the currently executing task. If I want to see the trace for all the tasks I need a fully thread aware FreeRTOS plug-in of the type provided by Segger, IAR and Code Confidence.
It doesn't provide mapping to meaningful symbol
The "standard" way to perform this mapping is by using addr2line. Something like:
addr2line -fe a.out 0x40076b 0x400796 0x4007bd ...
Update:
I want on the fly convert ...
Well, you should have asked for that then.
It's a simple matter of writing code. You need to write code that will map address ranges to symbol names (just like addr2line does).
On an ELF platform, this is actually quite simple: read Elf32_Syms from .symtab section to build address to symbol map, and look up your addresses in that map. You'll also need to read corresponding symbol names from .strtab section (Elf32_Sym.st_name is the offset into .strtab).

C interface: does failwith() leak memory?

I'm trying to work with a C interface generated using camlidl. The library I'm working with returns an error code by allocating and filling an in/out argument char* error_message and returning it. After the function call, I check the error code for non-zero... if true, I call caml_failwith(error_message) to throw an OCaml exception using the library error message.
However, I started digging a bit, because throwing the exception looks as though it will terminate the function and never free the error message. Consider this mock code:
/* in the C stub function call... */
double _res;
int error = 0;
char* error_message = NULL;
// if this function errors, it will set error to non-zero
// and strdup something into error_message
_res = call_library_function(&error, error_message);
if (error) {
caml_failwith(error_message);
free(error_message); // NEVER CALLED?
}
/* code to copy result to an OCaml value and return */
The exception func caml_failwith(s) implementation is in runtime/fail_*.c, but it basically just calls caml_raise_with_string, which is:
CAMLparam1(tag);
value v_msg = caml_copy_string(msg);
caml_raise_with_arg(tag, v_msg);
CAMLnoreturn;
So, it copies the string to the OCaml value with caml_copy_string, and then raises the arg and no-returns. In short, error_message is lost.
...Right? What am I missing here... I could use canned strings but that makes dynamic error messages impossible. I could maybe use static char*, though it's not thread safe any more without a bunch of work. Is there any way to call caml_failwith, using a plain old dynamic char*, and not have it cause a leak?
EDIT: I thought of one solution...
char error_message_buf[100] = {'\0'};
double _res;
// ... rest of local vars and service call ...
if (error) {
strncpy(error_message_buf, error_message, 99)
free(error_message);
caml_failwith(error_message_buf);
}
... but man that's ugly. strncpy to the stack just to turn around and caml_copy_string again? Plus, it sets a hardcoded cap on error message length. Still, if it's the only way not to leak...
caml_failwith() is designed so you can call it with a constant string, which is a very common case:
caml_failwith("float_of_string");
So, you can't expect it to free its argument.
I don't personally consider this a space leak, it's just how the function is designed.
Your solution of copying the message first seems reasonable (and not particularly ugly) to me.
(This, in essence, is why I switched from C to OCaml many years ago.)

Get the calling object or method in d

Somewhat related to my previous question here
Is there a way to get the calling Object from within a function or method in d?
example:
class Foo
{
public void bar()
{
auto ci = whoCalledMe();
// ci should be something that points me to baz.qux, _if_ baz.qux made the call
}
}
class Baz
{
void qux()
{
auto foo = new Foo();
foo.bar();
}
}
Questions:
Does something like whoCalledMe exist? and if so, what is it called?
if something does exist, can it be used at compile time (in a template) and if so, how?
Alternatively;
is it possible to get access to the call stack at runtime? like with php's debug_backtrace?
To expand on what CyberShadow said, since you can get the fully qualified name of the function by using __FUNCTION__, you can also get the function as a symbol using a mixin:
import std.stdio;
import std.typetuple;
void callee(string file=__FILE__, int line=__LINE__, string func=__FUNCTION__)()
{
alias callerFunc = TypeTuple!(mixin(func))[0];
static assert(&caller == &callerFunc);
callerFunc(); // will eventually overflow the stack
}
void caller()
{
callee();
}
void main()
{
caller();
}
The stack will overflow here since these two functions end up calling each other recursively indefinitely.
It's not directly possible to get information about your "caller". You might have some luck getting the address from the call stack, but this is a low-level operation and depends on things such as whether your program was compiled with stack frames. After you have the address, you could in theory convert it to a function name and line number, provided debugging symbols are available for your program's binary, but (again) this is highly platform-specific and depends on the toolchain used to compile your program.
As an alternative, you might find this helpful:
void callee(string file=__FILE__, int line=__LINE__, string func=__FUNCTION__)()
{
writefln("I was called by %s, which is in %s at line %d!", func, file, line);
}
void caller()
{
// Thanks to IFTI, we can call the function as usual.
callee();
}
But note that you can't use this trick for non-final class methods, because every call to the function will generate a new template instance (and the compiler needs to know the address of all virtual methods of a class beforehand).
Finding the caller is something debuggers do and generally requires having built the program with symbolic debug information switches turned on. Reading the debug info to figure this out is highly system dependent and is pretty advanced.
The exception unwinding mechanism also finds the caller, but those tables are not generated for functions that don't need them, and the tables do not include the name of the function.

Portable C++ Stack Trace on Exception

I am writing a library that I would like to be portable. Thus, it should not depend on glibc or Microsoft extensions or anything else that is not in the standard. I have a nice hierarchy of classes derived from std::exception that I use to handle errors in logic and input. Knowing that a particular type of exception was thrown at a particular file and line number is useful, but knowing how the execution got there would be potentially much more valuable, so I have been looking at ways of acquiring the stack trace.
I am aware that this data is available when building against glibc using the functions in execinfo.h (see question 76822) and through the StackWalk interface in Microsoft's C++ implementation (see question 126450), but I would very much like to avoid anything that is not portable.
I was thinking of implementing this functionality myself in this form:
class myException : public std::exception
{
public:
...
void AddCall( std::string s )
{ m_vCallStack.push_back( s ); }
std::string ToStr() const
{
std::string l_sRet = "";
...
l_sRet += "Call stack:\n";
for( int i = 0; i < m_vCallStack.size(); i++ )
l_sRet += " " + m_vCallStack[i] + "\n";
...
return l_sRet;
}
private:
...
std::vector< std::string > m_vCallStack;
};
ret_type some_function( param_1, param_2, param_3 )
{
try
{
...
}
catch( myException e )
{
e.AddCall( "some_function( " + param_1 + ", " + param_2 + ", " + param_3 + " )" );
throw e;
}
}
int main( int argc, char * argv[] )
{
try
{
...
}
catch ( myException e )
{
std::cerr << "Caught exception: \n" << e.ToStr();
return 1;
}
return 0;
}
Is this a terrible idea? It would mean a lot of work adding try/catch blocks to every function, but I can live with that. It would not work when the cause of the exception is memory corruption or lack of memory, but at that point you are pretty much screwed anyway. It may provide misleading information if some functions in the stack do not catch exceptions, add themselves to the list, and rethrow, but I can at least provide a guarantee that all of my library functions do so. Unlike a "real" stack trace I will not get the line number in calling functions, but at least I would have something.
My primary concern is the possibility that this will cause a slowdown even when no exceptions are actually thrown. Do all of these try/catch blocks require an additional set-up and tear-down on each function invocation, or is somehow handled at compile-time? Or are there other issues I have not considered?
I think this is a really bad idea.
Portability is a very worthy goal, but not when it results in a solution that is intrusive, performance-sapping, and an inferior implementation.
Every platform (Windows/Linux/PS2/iPhone/etc) I've worked on has offered a way to walk the stack when an exception occurs and match addresses to function names. Yes, none of these are portable but the reporting framework can be and it usually takes less than a day or two to write a platform-specific version of stack walking code.
Not only is this less time than it'd take creating/maintaining a cross-platform solution, but the results are far better;
No need to modify functions
Traps crashes in standard or third party libraries
No need for a try/catch in every function (slow and memory intensive)
Look up Nested Diagnostic Context once. Here is a little hint:
class NDC {
public:
static NDC* getContextForCurrentThread();
int addEntry(char const* file, unsigned lineNo);
void removeEntry(int key);
void dump(std::ostream& os);
void clear();
};
class Scope {
public:
Scope(char const *file, unsigned lineNo) {
NDC *ctx = NDC::getContextForCurrentThread();
myKey = ctx->addEntry(file,lineNo);
}
~Scope() {
if (!std::uncaught_exception()) {
NDC *ctx = NDC::getContextForCurrentThread();
ctx->removeEntry(myKey);
}
}
private:
int myKey;
};
#define DECLARE_NDC() Scope s__(__FILE__,__LINE__)
void f() {
DECLARE_NDC(); // always declare the scope
// only use try/catch when you want to handle an exception
// and dump the stack
try {
// do stuff in here
} catch (...) {
NDC* ctx = NDC::getContextForCurrentThread();
ctx->dump(std::cerr);
ctx->clear();
}
}
The overhead is in the implementation of the NDC. I was playing with a lazily evaluated version as well as one that only kept a fixed number of entries as well. The key point is that if you use constructors and destructors to handle the stack so that you don't need all of those nasty try/catch blocks and explicit manipulation everywhere.
The only platform specific headache is the getContextForCurrentThread() method. You can use a platform specific implementation using thread local storage to handle the job in most if not all cases.
If you are more performance oriented and live in the world of log files, then change the scope to hold a pointer to the file name and line number and omit the NDC thing altogether:
class Scope {
public:
Scope(char const* f, unsigned l): fileName(f), lineNo(l) {}
~Scope() {
if (std::uncaught_exception()) {
log_error("%s(%u): stack unwind due to exception\n",
fileName, lineNo);
}
}
private:
char const* fileName;
unsigned lineNo;
};
This will give you a nice stack trace in your log file when an exception is thrown. No need for any real stack walking, just a little log message when an exception is being thrown ;)
I don't think there's a "platform independent" way to do this - after all, if there was, there wouldn't be a need for StackWalk or the special gcc stack tracing features you mention.
It would be a bit messy, but the way I would implement this would be to create a class that offers a consistent interface for accessing the stack trace, then have #ifdefs in the implementation that use the appropriate platform-specific methods to actually put the stack trace together.
That way your usage of the class is platform independent, and just that class would need to be modified if you wanted to target some other platform.
In the debugger:
To get the stack trace of where an exception is throw from I just stcik the break point in std::exception constructor.
Thus when the exception is created the debugger stops and you can then see the stack trace at that point. Not perfect but it works most of the time.
Stack managing is one of those simple things that get complicated very quickly. Better leave it for specialized libraries. Have you tried libunwind? Works great and AFAIK it's portable, though I've never tried it on Windows.
This will be slower but looks like it should work.
From what I understand the problem in making a fast, portable, stack trace is that the stack implementation is both OS and CPU specific, so it is implicitly a platform specific problem. An alternative would be to use the MS/glibc functions and to use #ifdef and appropriate preprocessor defines (e.g. _WIN32) to implement the platform specific solutions in different builds.
Since stack usage is highly platform and implementation dependent, there is no way to do it directly that is completely portable. However, you could build a portable interface to a platform and compiler specific implementation, localizing the issues as much as possible. IMHO, this would be your best approach.
The tracer implementation would then link to whatever platform specific helper libraries are available. It would then operate only when an exception occurs, and even then only if you called it from a catch block. Its minimal API would simply return a string containing the whole trace.
Requiring the coder to inject catch and rethrow processing in the call chain has significant runtime costs on some platforms, and imposes a large future maintenance cost.
That said, if you do choose to use the catch/throw mechanism, don't forget that even C++ still has the C preprocessor available, and that the macros __FILE__ and __LINE__ are defined. You can use them to include the source file name and line number in your trace information.