std::cout << symbol_location_ptr(f.address()); // outputs `some/path/test.exe`
2017-03-08 22:59 GMT+03:00 mbartosik via Boost
I see that Boost.stacktrace is up for review March 17, 2017 - March 26, 2017
I've got some broad feedback. I'm in a race to comment before I go on vacation on Friday, so I'm sorry if I've missed something or misunderstood. I will try and follow the thread while on vacation - but not sure that will happen.
Thanks a lot for the feedback!
1) Resolving function names can be VERY expensive. Potentially it requires multi-megabyte files to be loaded and parsed. It is not clear to me that the resolution of frame.name() is going to be deferred. I have written a _lot_ of stack tracing code, and have usually in practice needed something that is fast and efficient to collect stack trace(s), but which allows deferring of the cost of resolving symbolic information until I really need it. In the extreme example I had some code which speculatively collected 100,000's of stack traces, but only symbolically resolved 10's of them. Thus the gathering of the 100,000's of traces had to be very very efficient (only the return addresses being saved) but the symbolic resolution did not have to be so fast. This also solved the issue of working within signals which I also had to do, indeed the code had been used to arguably work at an even lower level than signal handlers -- but more on that would get off topic.
I think that the interface needs to reflect this. Or at a minimum clearly state that symbol resolution will be delayed until absolutely necessary -- I think that it is best if the interface reflects this.
In addition to my own code, the company I currently work for has a multi-platform stack trace library which also defers symbols resolution.
Also until the symbols are resolved I think that the space requirement for a frame should be kept to the minimum (i.e. one pointer). This may necessitate two classes e.g. raw_stacktrace and symbolic_stacktrace with a means to convert between them, the symbolic_stacktrace should be all that is needed by default i.e. for most simple case users, potentially that means that having stacktrace and raw_stacktrace is better (raw_stacktrace only having a single pointer for each raw_frame).
boost::stacktrace::stacktrace class only stores raw pointers. Names resolving happens only when you call frame::name(). I'll update the docs to make that more explicit. I see no need in `symbolic_stacktrace` because such class * usable only if multiple frame::name() calls for the same frame happen (which is a very rare case) * could be easily build by users Tell me if I'm wrong or missed some point.
2) Tracing optimized code on some architectures can be really quite difficult. Especially when there are performance constraints (for example on Microsoft x86 should FPO information be loaded, should the whole .pdb file be loaded to walk the stack). So I would suggest a user specified function could be used to provide some choice in the algorithm for how walk the stack back, with some default.
How does such function shall look like? Could you please give an example?
3) Modules / libraries. Something else I have found useful is the ability to examine a frame and find out the code module e.g. a .dll or .so from it. That then raises the possibility of another object in addition to stacktrace and frame. Members that I have found useful on a module object are things like path, load address, length (maybe begin/end for the address in memory), name, version, copyright notice (this can get rather platform specific).
This is a part of Boost.DLL library. In boost_1_64 it will have a `boost::dll::symbol_location_ptr` so you can write the following code: stacktrace st; // no symbol names extraction, only storing frame addresses frame f = st[0]; // copying a pointer under the hood std::cout << f; // outputs `foo() at source/path/foo.cpp:42`. Only at this line function name and source location are retrieved.
A boost::stacktrace is definitely needed. I'm hoping that we'll get one that can meet more than the simple case needs.
- Mark
Great thanks for the feedback! Are there more usecases that the library does not meet? -- Best regards, Antony Polukhin