Use Relative Virtual Addresses to allow their decoding without knowing the base address#200
Conversation
apolukhin
left a comment
There was a problem hiding this comment.
Looks good! Requested a few changes. Do you have ideas, how to autotest the offsets?
The simplest solution might be to expect addresses in some range (maybe it's possible to read it from the file itself - ELF?), but this won't be very strict and will miss small differences. A more complex way would be to test executables that have debug symbols in separate files (.pdb and unstripped/stripped with --only-keep-debug). For Windows, Dbghelp is sufficient to convert RVA to a symbol. The library is available on the Another thing that comes to mind is that in an How complex could such a test be? I can imagine it being run with a lot of setups, so it should use some platform specific libs or tools. |
Just make a smoke test. Check that the address is less than the size of a binary you are working with. Path to the binary could be obtained from argv[0], and the size could be retrieved via |
| { | ||
| const auto frame = to_string(boost::stacktrace::stacktrace(0, 1).as_vector().front()); | ||
|
|
||
| // Skip the test if the frame does not contain an address |
There was a problem hiding this comment.
I was trying to use BOOST_STACKTRACE_TEST_SHOULD_OUTPUT_READABLE_NAMES but there were configurations were it was set to 0, but the stacktrace had a function name included. Let me know if you're fine with this part.
| } | ||
|
|
||
| int main() { | ||
| std::size_t get_file_size(const char* file_name) { |
There was a problem hiding this comment.
Should these helper functions be here or you prefer to move them to test_imp?
|
Many thanks for the PR! |
Boost `1.88.0` introduced a feature [^1] that makes use of the Windows API, but it uses API functions that are only available with `PSAPI_VERSION >= 2` and Windows VISITA only supports `PSAPI_VERSION == 1`. Actually, that new feature can also be disabled by setting the `BOOST_STACKTRACE_DISABLE_OFFSET_ADDR_BASE` macro, but since it seems to be a useful feature and isn't even disabled by default, we can just drop it that ancient Windows version instead of disabling it. [^1]: boostorg/stacktrace#200
Boost `1.88.0` introduced a feature [^1] that makes use of the Windows API, but it uses API functions that are only available with `PSAPI_VERSION >= 2` and Windows VISTA only supports `PSAPI_VERSION == 1`. Actually, that new feature can also be disabled by setting the `BOOST_STACKTRACE_DISABLE_OFFSET_ADDR_BASE` macro, but since it seems to be a useful feature and isn't even disabled by default, we can just drop it that ancient Windows version instead of disabling it. [^1]: boostorg/stacktrace#200
Instead of printing absolute addresses use relative ones so they can be used later to decode the stack trace.
Motivation
It’s quite common to release apps without debug symbols while keeping them internally. Currently the lib prints absolute addresses which require the base address to decode them using symbols. With this change, the base address won’t be needed as values are relative to the beginning of the loaded module/binary.
The implementation for unix is straightforward as the existing code is used. For Windows, I’ve implemented similar logic using Windows API.
Manual testing of Windows implementation
Here are 2 runs of
trivial_windbg_lib.exewith .pdb and without .pdb file:I’ve also decoded the returned address using x64dbg running
trivial_windbg_lib.exe+0x0000000000001DE3:Control
As it was suggested in #180, the new logic is enabled by default, but can be disabled with
BOOST_STACKTRACE_DISABLE_OFFSET_ADDR_BASE(With non header-only mode, it requires rebuilding the lib)Further work
If the implementation would be accepted, I’m happy to do the rest of work, like changes in documentation or test cases. It’s my first contribution to this repo, so I would be very grateful for some guidance what is required.