3131void print_stacktrace (FILE* output, int start_idx, bool demangling, int maxdepth, bool omit_above_own)
3232{
3333 // 32 vs. 64bit
34- #define ADDRESSDISPLAYLENGTH ((sizeof (long )==8 )?12 :8 )
34+ static constexpr auto ADDRESSDISPLAYLENGTH = (sizeof (long ) == 8 ) ? 12 : 8 ;
35+
3536 void *callstackArray[32 ]= {nullptr }; // the less resources the better...
3637 const int currentdepth = backtrace (callstackArray, static_cast <int >(getArrayLength (callstackArray)));
38+ if (currentdepth == 0 ) {
39+ fputs (" Callstack could not be obtained (backtrace)\n " , output);
40+ return ;
41+ }
42+ if (currentdepth == getArrayLength (callstackArray)) {
43+ fputs (" Callstack might be truncated\n " , output);
44+ }
3745 // set offset to 1 to omit the printing function itself
3846 int offset=start_idx+1 ; // some entries on top are within our own exception handling code or libc
3947 if (maxdepth<0 )
@@ -43,61 +51,78 @@ void print_stacktrace(FILE* output, int start_idx, bool demangling, int maxdepth
4351
4452 char **symbolStringList = backtrace_symbols (callstackArray, currentdepth);
4553 if (!symbolStringList) {
46- fputs (" Callstack could not be obtained\n " , output);
54+ fputs (" Callstack could not be obtained (backtrace_symbols) \n " , output);
4755 return ;
4856 }
4957
5058 fputs (" Callstack:\n " , output);
5159 bool own_code = false ;
5260 char demangle_buffer[2048 ]= {0 };
53- for (int i = offset ; i < maxdepth; ++i) {
61+ for (int i = 0 ; i < maxdepth; ++i) {
5462 const char * const symbolString = symbolStringList[i];
5563 // TODO: implement parsing for __APPLE__
64+ // 0 test-signalhandler 0x0000000100dbf42c _Z16print_stacktraceP7__sFILEibib + 124
65+
66+ /*
67+ * examples:
68+ * ./test-signalhandler(_Z16print_stacktraceP8_IO_FILEibib+0xa1) [0x55cb65e41464]
69+ * ./test-signalhandler(+0xf9d9) [0x55cb65e3c9d9]
70+ */
71+
5672 // skip all leading libc symbols so the first symbol is our code
5773 if (omit_above_own && !own_code) {
5874 if (strstr (symbolString, " /libc.so.6" ) != nullptr )
5975 continue ;
6076 own_code = true ;
61- offset = i; // make sure the numbering is continous if we omit frames
77+ offset = i; // make sure the numbering is continuous if we omit frames
6278 }
6379 const char * realnameString = nullptr ;
64- const char * const firstBracketName = strchr (symbolString, ' (' );
65- const char * const firstBracketAddress = strchr (symbolString, ' [' );
66- const char * const secondBracketAddress = strchr (firstBracketAddress, ' ]' );
67- const char * const beginAddress = firstBracketAddress+3 ;
68- const int addressLen = int (secondBracketAddress-beginAddress);
69- const int padLen = (ADDRESSDISPLAYLENGTH-addressLen);
70- if (demangling && firstBracketName) {
71- const char * const plus = strchr (firstBracketName, ' +' );
72- if (plus && (plus>(firstBracketName+1 ))) {
73- char input_buffer[1024 ]= {0 };
74- strncpy (input_buffer, firstBracketName+1 , plus-firstBracketName-1 );
75- size_t length = getArrayLength (demangle_buffer);
76- int status=0 ;
77- // We're violating the specification - passing stack address instead of malloc'ed heap.
78- // Benefit is that no further heap is required, while there is sufficient stack...
79- realnameString = abi::__cxa_demangle (input_buffer, demangle_buffer, &length, &status); // non-NULL on success
80+ if (demangling) {
81+ const char * const firstBracketName = strchr (symbolString, ' (' );
82+ if (firstBracketName) {
83+ const char * const plus = strchr (firstBracketName, ' +' );
84+ if (plus && (plus>(firstBracketName+1 ))) {
85+ char input_buffer[1024 ]= {0 };
86+ strncpy (input_buffer, firstBracketName+1 , plus-firstBracketName-1 );
87+ size_t length = getArrayLength (demangle_buffer);
88+ int status=0 ;
89+ // We're violating the specification - passing stack address instead of malloc'ed heap.
90+ // Benefit is that no further heap is required, while there is sufficient stack...
91+ realnameString = abi::__cxa_demangle (input_buffer, demangle_buffer, &length, &status); // non-NULL on success
92+ }
8093 }
8194 }
8295 const int ordinal=i-offset;
8396 fprintf (output, " #%-2d 0x" ,
8497 ordinal);
98+
99+ const char * const firstBracketAddress = strchr (symbolString, ' [' );// TODO: check
100+ const char * const secondBracketAddress = strchr (firstBracketAddress, ' ]' ); // TODO: check
101+ const int padLen = [&]() {
102+ // TODO: handle firstBracketAddress being NULL
103+ const char * const beginAddress = firstBracketAddress+3 ;
104+ const int addressLen = int (secondBracketAddress-beginAddress);
105+ return (ADDRESSDISPLAYLENGTH-addressLen);
106+ }();
85107 if (padLen>0 )
86108 fprintf (output, " %0*d" ,
87- padLen, 0 );
109+ padLen,
110+ 0 );
88111 if (realnameString) {
89112 fprintf (output, " %.*s in %s\n " ,
90- static_cast <int >(secondBracketAddress - firstBracketAddress - 3 ), firstBracketAddress+3 ,
113+ static_cast <int >(secondBracketAddress - firstBracketAddress - 3 ),
114+ firstBracketAddress+3 ,
91115 realnameString);
92116 } else {
93117 fprintf (output, " %.*s in %.*s\n " ,
94- static_cast <int >(secondBracketAddress - firstBracketAddress - 3 ), firstBracketAddress+3 ,
95- static_cast <int >(firstBracketAddress - symbolString), symbolString);
118+ static_cast <int >(secondBracketAddress - firstBracketAddress - 3 ),
119+ firstBracketAddress+3 ,
120+ static_cast <int >(firstBracketAddress - symbolString),
121+ symbolString);
96122 }
97123 }
98124 // NOLINTNEXTLINE(bugprone-multi-level-implicit-pointer-conversion) - code matches the documented usage
99125 free (symbolStringList);
100- #undef ADDRESSDISPLAYLENGTH
101126}
102127
103128#endif // USE_UNIX_BACKTRACE_SUPPORT
0 commit comments