public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/112649] New: [c++23] in presence of inline functions and debug-info stacktrace reports the deepest callee
@ 2023-11-21 14:16 vincenzo.innocente at cern dot ch
  0 siblings, 0 replies; only message in thread
From: vincenzo.innocente at cern dot ch @ 2023-11-21 14:16 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112649

            Bug ID: 112649
           Summary: [c++23] in presence of inline functions and debug-info
                    stacktrace reports the deepest callee
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vincenzo.innocente at cern dot ch
  Target Milestone: ---

Created attachment 56657
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=56657&action=edit
a small demo demonstating the description.

feature or defect?
or missing feature in std::stacktrace...

what I find disturbing is that the "symbol name" is different for the very same
pc depending if it has been compiled with "-g" or not:
in case of debug-info it is set to the deepest callee, w/o to the outermost
caller.

maybe it is a issue for the libstd committee?

DEMO:
just compile the attached demo program and compile it with
c++ -std=c++23 stackTraceDemo.cpp -lstdc++exp -O2 -DINCLUDE='' -g
and run it
than without -g
one can also try to run gdb to compare with the demo output.
```
gdb ./a.out
b instrumentedFunc
run
where
```

Details:
in libstdc++-v3/src/c++23/stacktrace.cc
   123  bool
   124  stacktrace_entry::_Info::_M_populate(native_handle_type pc)
   125  {
   126    auto cb = [](void* self, uintptr_t, const char* filename, int lineno,
   127                 const char* function) -> int
   128    {
   129      auto& info = *static_cast<_Info*>(self);
   130      info._M_set_desc(function);
   131      info._M_set_file(filename);
   132      if (info._M_line)
   133        *info._M_line = lineno;
   134      return function != nullptr;
   135    };
   136    const auto state = init();
   137    if (::__glibcxx_backtrace_pcinfo(state, pc, +cb, err_handler, this))
   138      return true;

according to doc __glibcxx_backtrace_pcinfo
* Given PC, a program counter in the current program, call the
   callback function with filename, line number, and function name
   information.  This will normally call the callback function exactly
   once.  However, if the PC happens to describe an inlined call, and
   the debugging information contains the necessary information, then
   this may call the callback function multiple times.  This will make
   at least one call to either CALLBACK or ERROR_CALLBACK.  This
   returns the first non-zero value returned by CALLBACK, or 0.  */

From my tests last sentence means that if the callback does not return 0 it may
be called again.
So in the current implementation it will be called just once even in presence
of inline functions and therefore the stacktrace-entry will be set to the
deepest callee.
If one waits till last call (returning always "false") one will be able to set
the entry to 
the outermost caller or even record the full call chain (as GDB does).
This last option does not seem to fit std::backtrace interface.


--------------
here is the output of the demo (I prefer to print the stacktrace reversed)
# is from the stacktrace entry
>> is from __glibcxx_backtrace_pcinfo returning always "false"

[innocent@patatrack01 demos]$ c++ -std=c++23 stackTraceDemo.cpp -lstdc++exp -O2
-DINCLUDE=''; ./a.out
#0 0xffffffffffffffff  :0
#1 0x40164d _start :0
#2 0x7f4412f23d84 __libc_start_main :0
#3 0x40159a main :0
#4 0x401eeb func(int) :0
#5 0x401ab0 instrumentedFunc(int) :0
10
[innocent@patatrack01 demos]$ c++ -std=c++23 stackTraceDemo.cpp -lstdc++exp -O2
-DINCLUDE='' -g; ./a.out
#0 0xffffffffffffffff  :0
#1 0x40164d _start :0
#2 0x7ff80f90ed84 __libc_start_main :0
#3 0x40159a main
/data/user/innocent/MallocProfiler/demos/stackTraceDemo.cpp:116
>> 1 main /data/user/innocent/MallocProfiler/demos/stackTraceDemo.cpp:116
#4 0x401eeb nestedFunc2(int)
/data/user/innocent/MallocProfiler/demos/stackTraceDemo.cpp:101
>> 1 _Z11nestedFunc2i /data/user/innocent/MallocProfiler/demos/stackTraceDemo.cpp:101
>> 2 _Z10nestedFunci /data/user/innocent/MallocProfiler/demos/stackTraceDemo.cpp:106
>> 3 _Z4funci /data/user/innocent/MallocProfiler/demos/stackTraceDemo.cpp:112
#5 0x401ab0 instrumentedFunc(int)
/data/user/innocent/MallocProfiler/demos/stackTraceDemo.cpp:91
>> 1 _Z16instrumentedFunci /data/user/innocent/MallocProfiler/demos/stackTraceDemo.cpp:91
10
[innocent@patatrack01 demos]$ gdb ./a.out
GNU gdb (GDB) Red Hat Enterprise Linux 8.2-19.el8
...
Reading symbols from ./a.out...done.
(gdb) b instrumentedFunc
Breakpoint 1 at 0x401a90: file
/afs/cern.ch/work/i/innocent/public/w5/include/c++/14.0.0/bits/new_allocator.h,
line 88.
(gdb) run
Starting program: /data/user/innocent/MallocProfiler/demos/a.out
Breakpoint 1, instrumentedFunc (c=4) at
/afs/cern.ch/work/i/innocent/public/w5/include/c++/14.0.0/bits/new_allocator.h:88
88            __new_allocator() _GLIBCXX_USE_NOEXCEPT { }
(gdb) where
#0  instrumentedFunc (c=4) at
/afs/cern.ch/work/i/innocent/public/w5/include/c++/14.0.0/bits/new_allocator.h:88
#1  0x0000000000401eec in nestedFunc2 (c=<optimized out>) at
stackTraceDemo.cpp:112
#2  nestedFunc (c=<optimized out>) at stackTraceDemo.cpp:106
#3  func (c=<optimized out>) at stackTraceDemo.cpp:112
#4  0x000000000040159b in main (argc=<optimized out>) at stackTraceDemo.cpp:116

well the gdb stacktrace is also strange as it reports a pc off by one for
nestedFunc2 (and the line number is wrong as it correspond to the call to
nestedFunc in func...
the one from __glibcxx_backtrace_pcinfo looks correct.

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-11-21 14:16 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-21 14:16 [Bug libstdc++/112649] New: [c++23] in presence of inline functions and debug-info stacktrace reports the deepest callee vincenzo.innocente at cern dot ch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).