-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Disable stacktraces if ('full') symbols aren't available (or make this query-able) #84
Comments
Hi @VelocityRa, I see how that trace can be misleading and that's definitely something I'd like to address. Defining what it means for a trace to be "full" or not is slightly unclear because it's not uncommon for some information to be missing (e.g. libraries might not be built with debug symbols) but the rest of the information should be accurate and hopefully useful. Additionally, it's often not known whether there will be useful information until after attempting to resolve the trace. I think ideally in this situation even when symbols aren't present for one object the trace should have blank or partially blank frames with as much information as was possible to extract, for example Stack trace (most recent call first):
#0 0x00000001034fd788 at /Users/rifkin/foo/cpptrace/build/test
#1 0x00000001034fd758 at /Users/rifkin/foo/cpptrace/build/test
#2 0x00000001034fd728 at /Users/rifkin/foo/cpptrace/build/test
#3 0x00000001034fd908 in buzz() at /Users/rifkin/foo/cpptrace/build/bar.cpp:4:2
#4 0x00000001034fd978 in biz() at /Users/rifkin/foo/cpptrace/build/bar.cpp:8:2
#5 0x00000001034fd988 in bar() at /Users/rifkin/foo/cpptrace/build/bar.cpp:12:2
#6 0x00000001034fd8d8 at /Users/rifkin/foo/cpptrace/build/test
#7 0x00000001034fd8e8 at /Users/rifkin/foo/cpptrace/build/test
```or even
```c
Stack trace (most recent call first):
#0 0x00000001034fd788
#1 0x00000001034fd758
#2 0x00000001034fd728
#3 0x00000001034fd908 in buzz() at /Users/rifkin/foo/cpptrace/build/bar.cpp:4:2
#4 0x00000001034fd978 in biz() at /Users/rifkin/foo/cpptrace/build/bar.cpp:8:2
#5 0x00000001034fd988 in bar() at /Users/rifkin/foo/cpptrace/build/bar.cpp:12:2
#6 0x00000001034fd8d8
#7 0x00000001034fd8e8 Personally I'd lean more towards providing as much information as possible as opposed to conditionally disabling stacktrace generation, as long as what is there is accurate. Does that work for your use case? I don't think frames should blindly resolve to the closest symbol if their actual entry isn't there but I can double check the logic. Ideally it is returning an error under the hood if a symbol isn't found. It would be helpful to know a little more about how you are compiling and what's going on here. Are you using msvc? Are optimizations on? I'm surprised to not see a I'm definitely surprised to see a |
I'm going to close this for now as I think I need additional information to proceed. If there's any additional info or if you have any more library feedback please let me know! |
Right, forgot about this sorry! I'm compiling on MSVC on Release mode (so optimizations on). Using CMake with vcpkg, cpptrace version 0.3.1. Specific flags I see in my
That's the config generating traces like the one above, or this one I just got from another test:
I wasn't throwing from the main thread so that's to be expected afaik. After testing this on Debug I see I can only see I get this when throwing from the main thread without symbols (on Release config):
All examples have been from the
I would be fine with that - assuming all printed symbol names are correct. I would still want to be able query for whether full symbols are available ( The above issue is still a library bug though, as far as I understand. As said on my main post, my project is using libtpms (https://github.com/stefanberger/libtpms, via a simple custom vcpkg port). The printed symbols are from there. Maybe using this is required to repro the issue. I'm willing to help with debugging this further. I can make changes to cpptrace itself if it'd help narrow down the issue. |
Thank you, I’ll take a look tonight |
Ok, I've tested locally trying to reproduce anything but I've been unsuccessful so far. I tested
Release:
```
Stack trace (most recent call first):
#0 0x00007ff65c4b2022 in ??
#1 0x00007ff65c4b165a in ??
#2 0x00007ffe3c279362 in recalloc
#3 0x00007ffe3e57257c in BaseThreadInitThunk
#4 0x00007ffe3e94aa57 in RtlUserThreadStart
0> test+0x2057
1> test+0x165B
2> ucrtbase!recalloc+0xA3
3> KERNEL32!BaseThreadInitThunk+0x1D
4> ntdll!RtlUserThreadStart+0x28
cpptrace::runtime_error:
Stack trace (most recent call first):
#0 0x00007ff65c4b1e37 in ??
#1 0x00007ff65c4b208a in ??
#2 0x00007ff65c4b165a in ??
#3 0x00007ffe3c279362 in recalloc
#4 0x00007ffe3e57257c in BaseThreadInitThunk
#5 0x00007ffe3e94aa57 in RtlUserThreadStart
-- main --
Stack trace (most recent call first):
#0 0x00007ff65c4b218a in ??
#1 0x00007ff65c4b2d6b in ??
#2 0x00007ffe3e57257c in BaseThreadInitThunk
#3 0x00007ffe3e94aa57 in RtlUserThreadStart
```
RelWithDebInfo:
```
Stack trace (most recent call first):
#0 0x00007ff736f52e92 in foo() at C:\Users\rifkin\Projects\test-cpptrace\test.cpp:9
#1 0x00007ff736f5210a in std::thread::_Invoke, 0>() at C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\include\thread:55
#2 0x00007ffe3c279362 in recalloc
#3 0x00007ffe3e57257c in BaseThreadInitThunk
#4 0x00007ffe3e94aa57 in RtlUserThreadStart
0> C:\Users\rifkin\Projects\test-cpptrace\test.cpp(10): test!foo+0x47
1> C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\include\thread(56): test!std::thread::_Invoke,0>+0xB
2> ucrtbase!recalloc+0xA3
3> KERNEL32!BaseThreadInitThunk+0x1D
4> ntdll!RtlUserThreadStart+0x28
[foobar](cpptrace::runtime_error):
Stack trace (most recent call first):
#0 0x00007ff736f52c67 in bar() at C:\Users\rifkin\Projects\test-cpptrace\test.cpp:6
#1 0x00007ff736f52efa in foo() at C:\Users\rifkin\Projects\test-cpptrace\test.cpp:13
#2 0x00007ff736f5210a in std::thread::_Invoke, 0>() at C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\include\thread:55
#3 0x00007ffe3c279362 in recalloc
#4 0x00007ffe3e57257c in BaseThreadInitThunk
#5 0x00007ffe3e94aa57 in RtlUserThreadStart
-- main --
Stack trace (most recent call first):
#0 0x00007ff736f5301a in main() at C:\Users\rifkin\Projects\test-cpptrace\test.cpp:23
#1 0x00007ff736f54a0f in __scrt_common_main_seh() at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
#2 0x00007ffe3e57257c in BaseThreadInitThunk
#3 0x00007ffe3e94aa57 in RtlUserThreadStart
```
Do you think you could try doing a And one more quick question, are you by chance doing this from within a signal handler? |
Part of the difficulty on the cpptrace side of things is that for the most part dbghelp does all the heavy lifting. Cpptrace doesn't even check to see what module an instruction pointer come from much less look for or load a .pdb. If you are interested, three things I can think of checking related to dbghelp handling
And if none of those are the issue... I'll be sad. If that's the case the issue would be in |
So, wrong here too.
I also tried your three suggestions to no avail. The first one results in
for Guess I'll have to resort to simply checking if a Thank you for your time, I appreciate it :) |
Thanks for the additional information. I’ll keep trying to reproduce and see what I can do. |
I have inherited
cpptrace::lazy_exception
to make my own type with some niceties, and I throw this exception type in my codebase.cpptrace adds a stacktrace in the
![image](https://private-user-images.githubusercontent.com/6632271/300283036-bcbc82cd-75ee-4e34-ab55-f6b0ae1db2c1.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjAzMzI0OTksIm5iZiI6MTcyMDMzMjE5OSwicGF0aCI6Ii82NjMyMjcxLzMwMDI4MzAzNi1iY2JjODJjZC03NWVlLTRlMzQtYWI1NS1mNmIwYWUxZGIyYzEucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MDcwNyUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDA3MDdUMDYwMzE5WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9ZjcyYTVhNjk0OWFkODYyNDZiOGMzZDExYmJmMjE4MmRkMDgwYzRmMWMyMjNlZWM0M2M4ZjBhZjM5NTk2NjcxNCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYWN0b3JfaWQ9MCZrZXlfaWQ9MCZyZXBvX2lkPTAifQ.LZgv3MV8fXpusx_7KHA6PMwpAckhSuZT92NZsYydkgo)
.what()
string as expected, but if symbols (in my case a.pdb
next to the.exe
) are not available, it results in bogus stacktraces like so:These appear to be func names from libtpms, a library that I'm using that presumably embeds dwarf symbols. The exception does not originate there however, presumably it picks them up because there are no other symbols available (so it picks the closest before the exception instruction pointers).
Is there a solution? Perhaps simply a way to detect whether 'full' symbols are available, so I can make my class not fetch the stacktrace if so? Or perhaps simply whether the
dbghelp
backend is available / was used for a stacktrace?Thanks for the awesome library!
The text was updated successfully, but these errors were encountered: