A couple notes/comments/documentation tweaks

This commit is contained in:
Jeremy Rifkin 2024-08-18 11:20:59 -05:00
parent 5558210cbe
commit 7621f2b277
No known key found for this signature in database
GPG Key ID: 19AA8270105E8EB4
2 changed files with 7 additions and 6 deletions

View File

@ -395,13 +395,14 @@ API functions:
references to traces returned by `cpptrace::raw_trace_from_current_exception`. references to traces returned by `cpptrace::raw_trace_from_current_exception`.
#### How it works #### How it works
C++ does not provide any language support for collecting stack traces when exceptions are thrown, however, exception C++ does not provide any language support for collecting stack traces when exceptions are thrown, however, exception
handling under both the Itanium ABI and by SEH (used to implement C++ exceptions on windows) involves unwinding the handling under both the Itanium ABI and by SEH (used to implement C++ exceptions on windows) involves unwinding the
stack twice, the first unwind searches for an appropriate `catch` handler, the second actually unwinds the stack and stack twice, the first unwind searches for an appropriate `catch` handler, the second actually unwinds the stack and
calls destructors. Since the stack remains intact during the search phase it's possible to collect a stack trace with calls destructors. Since the stack remains intact during the search phase it's possible to collect a stack trace with
zero overhead when the `catch` is considered for matching the exception. zero overhead when the `catch` is considered for matching the exception.
N.b.: Cpptrace uses the same mechanism proposed for use in [P2490R3][P2490R3]. N.b.: This mechanism is also discussed in [P2490R3][P2490R3].
#### Performance #### Performance
@ -413,8 +414,8 @@ nesting of handlers, either directly in code or as a result of the current call
mutliple times until the appropriate handler is found. mutliple times until the appropriate handler is found.
This should not matter for the vast majority applications given that performance very rarely is critical in throwing This should not matter for the vast majority applications given that performance very rarely is critical in throwing
paths, how exception handling is usually used, and the shallowness of most call stacks. However, it's an important paths, how exception handling is usually used, and the shallowness of most call stacks. However, it's something to be
consideration to be aware of. aware of.
To put the scale of this performance consideration into perspective: In my benchmarking I have found generation of raw To put the scale of this performance consideration into perspective: In my benchmarking I have found generation of raw
traces to take on the order of `75ns` per frame. Thus, even if there were 100 non-matching handlers before a matching traces to take on the order of `75ns` per frame. Thus, even if there were 100 non-matching handlers before a matching

View File

@ -132,7 +132,7 @@ namespace cpptrace {
uintptr_t start; uintptr_t start;
uintptr_t stop; uintptr_t stop;
stream>>start; stream>>start;
stream.ignore(1); stream.ignore(1); // dash
stream>>stop; stream>>stop;
if(stream.eof()) { if(stream.eof()) {
break; break;
@ -141,8 +141,8 @@ namespace cpptrace {
throw std::runtime_error("Failure reading /proc/self/maps"); throw std::runtime_error("Failure reading /proc/self/maps");
} }
if(page_addr >= start && page_addr < stop) { if(page_addr >= start && page_addr < stop) {
stream.ignore(1); stream.ignore(1); // space
char r, w, x; char r, w, x; // there's a private/shared flag after these but we don't need it
stream>>r>>w>>x; stream>>r>>w>>x;
if(stream.fail() || stream.eof()) { if(stream.fail() || stream.eof()) {
throw std::runtime_error("Failure reading /proc/self/maps"); throw std::runtime_error("Failure reading /proc/self/maps");