Bug 397476 - Heaptrack doesn't read symbols when callee is invoker via explicit dynamic loader
Summary: Heaptrack doesn't read symbols when callee is invoker via explicit dynamic lo...
Status: CONFIRMED
Alias: None
Product: Heaptrack
Classification: Applications
Component: general (other bugs)
Version First Reported In: unspecified
Platform: Debian testing Linux
: NOR normal
Target Milestone: ---
Assignee: Milian Wolff
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-08-15 08:42 UTC by Damian Szuberski
Modified: 2018-08-20 04:08 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed/Implemented In:
Sentry Crash Report:


Attachments
screenshot_1 (83.20 KB, image/png)
2018-08-16 06:28 UTC, Damian Szuberski
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Damian Szuberski 2018-08-15 08:42:56 UTC
Applies to heaptrack 1.0.0 and 1.1.0.

Heaptrack works perfectly well when invoked
$ heaptrack CALLEE

Heaptrack gathers data and produces the report but symbols in the stacktraces are properly resolved only for shared libraries linked to CALLEE. All memory allocations of CALLEE itself go into the generic unresolved symbol section
$ heaptrack /lib64/ld-linux-x86-64.so.2 CALLEE

from /usr/bin/heaptrack:
  echo "starting application, this might take some time..."
  LD_PRELOAD=$LIBHEAPTRACK_PRELOAD${LD_PRELOAD:+:$LD_PRELOAD} DUMP_HEAPTRACK_OUTPUT="$pipe" "$client" "$@"

I'm not sure if there is a way to either (1) inject LD_PRELOAD after dynamic linker is loaded but before CALLEE is executed (2) somehow "if-out" dynamic loaders out of heaptrack so they won't interfere with symbol resolution.
Comment 1 Milian Wolff 2018-08-15 08:48:13 UTC
I'm not sure I follow. Can you provide a minimal test application that shows the issue you are facing? I.e. give explicit output for failed/missing symbols.

What I gather from your report, it would mean that the manual test clients should all not work. But they do - for me. Can you try to be more specific please?
Comment 2 Damian Szuberski 2018-08-16 06:28:03 UTC
Created attachment 114451 [details]
screenshot_1
Comment 3 Damian Szuberski 2018-08-16 06:33:37 UTC
Thank your for fast reaction.

$ cat main.cpp
#include <iostream>

int main()
{
    std::cout << new int(6) << std::endl;
}

$ g++ -g -o main main.cpp
$ heaptrack ./main
$ heaptrack_print /home/szubersk/tmp/heaptrack/a/heaptrack.main.13091.gz | grep CALLS -A 6
MOST CALLS TO ALLOCATION FUNCTIONS
1 calls to allocation functions with 4B peak consumption from
main
  at /home/szubersk/tmp/heaptrack/a/main.cpp:5
  in /home/szubersk/tmp/heaptrack/a/main
1 calls with 4B peak consumption from:

$ heaptrack /lib64/ld-linux-x86-64.so.2  ./main
$ heaptrack_print heaptrack.ld-linux-x86-64.so.2.13132.gz | grep  CALLS -A 6 
MOST CALLS TO ALLOCATION FUNCTIONS
1 calls to allocation functions with 4B peak consumption from
0x7f4d7cd30182
  in /lib/x86_64-linux-gnu/ld-2.27.so
1 calls with 4B peak consumption from:
    __libc_start_main
      in /lib/x86_64-linux-gnu/libc.so.6

In addition please see the screenshot attached to see how visualizer shows that 4B allocation (<unresolved function>).
Comment 4 Milian Wolff 2018-08-17 20:12:42 UTC
ah, now I understand... I wonder how to resolve this - quite frankly I have no clue. When I strace this, there is basically no obvious difference between the two calls, except for the fact that heaptrack will believe that the main executable is ld instead of CALLEE, leading to the broken symbol resolution. We probably read /proc/self/cmdline too soon, but I wonder how we could delay that :(

May I ask why you need this? I.e. why not simply skip the explicit "interpreter" qualification?

If you need this urgently, then you'll have to help me by figuring out how to fix this in principle. I.e. try to talk to someone with knowledge in this area, maybe the people from glibc.
Comment 5 Damian Szuberski 2018-08-20 04:08:07 UTC
We run our software in restricted chroot for testing and deployment purposes hence sometimes we need to explicitly invoke ld loader instead of relying on what was hardcode in .interp section. I'll poke around it, maybe there is a way of skipping explicit loader invocation.

I reported this bug in a hope that you might now the solution, as of now I don't. I don't need this urgently :) I appreciate the support you're giving very much. I'll go over the libc code and contact its developers to get more information on this case.