New stack trace functions

With svenT’s tweaks (Windows) I can now see the stacktrace, but it’s still the one of the crash handler, did anyone found a way to show the actual exception?

What do you mean by “acutal exception”?

I am testing with a hand made crash:

unsigned char * test = NULL;
test[1000] = 'a'; //<< here it should crash

We all know this should crash imeadiately :slight_smile: Furthermore it must be a 0xC0000005 access violation.
We I look at my dmp with attached symbols and sources it shows me the exact line where it crashes.

This is how my crash file looks like:

0: TestCarshApp32: juce::SystemStats::getStackBacktrace + 0x7f
1: TestCarshApp32: GeneralUtils::appCrashReporter + 0x63
2: TestCarshApp32: juce::handleCrash + 0xf
3: UnhandledExceptionFilter + 0x164
4: RtlCreateUserThread + 0xaadc
5: RtlInitializeExceptionChain + 0x58

And this is my crash handler:

	File crashFile = getCrashReportFile();
	FileOutputStream fos(crashFile);
	fos.writeText(SystemStats::getStackBacktrace(),true,true);
	fos.flush();

Yeah same here, it’s the wrong thread that’s getting dumped.

sorry guys. I didn’t try Jules implementation of the stacktracer. I am still working with my old one that’s called MDUMP from codeproject. This is a Windows only solution. That’s why I am very exhited to see this in juce as well. I am not sure if it’s even possible to print out the right stack trace because you’ll need symbols (PDBs on VS2008) and in release mode you shouldn’t have symbols. That’s why dumping to a mini dump and reattachting it afterwards is a much more reasonable approach. Don’t you think?

XPlattform question: Is there a mini dump on Mac OS X (or even on Linux) as well? I have not found such thing. Are there symbol files available as well?

Just upgraded to 2.0.39 today, so I tried out the new getStackBacktrace() method. Jules, this example code attempts to demangle the given C++ name:

        String name( "_ZN4juce11SystemStats17getStackBacktraceEv" );
        int status = 0;
        char *demangled = abi::__cxa_demangle( name.toStdString().c_str(), nullptr, nullptr, &status );
        if ( status == 0 )
        {
            name = demangled;
        }
        free( demangled );

If the name cannot be demangled, it remains untouched; if it can be demangled, then we replace “name” with the demangled version. Instead of _ZN4juce11SystemStats17getStackBacktraceEv, this will show up as juce::SystemStats::getStackBacktrace(void).

Parsing the backtrace output to demangle names:

    String msg;
    String bt = SystemStats::getStackBacktrace();

    // The lines returned look like this on linux:
    //
    //      test/test.out(_ZN4juce11SystemStats17getStackBacktraceEv+0x2a) [0x53fdea]
    //
    // At the very least, attempt to parse out the names so we can properly demangle them.

    while( bt.isNotEmpty() )
    {
        // parse out the next line from the backtrace string and remove it from bt
        String line;
        const int eol = bt.indexOfChar( '\n' );
        if ( eol > 0 )
        {
            line = bt.substring( 0, eol - 1 );
            bt   = bt.substring( eol + 1 );
        }
        else
        {
            // no "\n" left, so consume the rest of the string
            line = bt;
            bt   = String::empty;
        }

        const int startParen = line.indexOfChar( '(' );
        const int closeParen = line.indexOfChar( ')' );
        const int plusOffset = line.lastIndexOfChar( '+' );
        if (    startParen  > 0             &&
                plusOffset  > startParen    &&
                closeParen  > plusOffset    )
        {
            // look like we have a string we can try and demangle
            String name( line.substring( startParen + 1, plusOffset ) );
            int status = 0;
            char *demangled = abi::__cxa_demangle( name.toStdString().c_str(), nullptr, nullptr, &status );
            if ( status == 0 )
            {
                // we have a better demangled name we can use -- replace it within the line
                name = " " + String(demangled) + " ";
                line = line.replaceSection( startParen + 1, plusOffset - startParen - 1, name );
            }
            free( demangled );
        }

        msg += line + '\n';
    }

I've figured out how to do this correctly on Windows. More info here: http://stackoverflow.com/questions/28099965/windows-c-how-can-i-get-a-useful-stack-trace-from-a-signal-handler

cheers

- Taylor

Btw this demangling mechanism is available in SR’s branch and I’ve opened a PR to get it into main JUCE.

3 Likes