No Output When Running Ltrace

No output when running ltrace

This may have to do with binaries being compiled with -z now. I created a quick test program (I'm using Ubuntu 16.04):

int main() {
write(0, "hello\n", 6);
return 0;
}

If I compile it with gcc -O2 test.c -o test then ltrace works:

$ ltrace ./test 
__libc_start_main(0x400430, 1, 0x7ffc12326528, 0x400550 <unfinished ...>
write(0, "hello\n", 6hello
) = 6
+++ exited (status 0) +++

However when I compile with gcc -O2 test.c -Wl,-z,relro -Wl,-z,now -o test2 then it doesn't:

$ ltrace ./test2 
hello
+++ exited (status 0) +++

You can check if a binary was compiled like so using scanelf from the pax-utils package on Ubuntu:

$ scanelf -a test*
TYPE PAX PERM ENDIAN STK/REL/PTL TEXTREL RPATH BIND FILE
ET_EXEC PeMRxS 0775 LE RW- R-- RW- - - LAZY test
ET_EXEC PeMRxS 0775 LE RW- R-- RW- - - NOW test2

Note the LAZY (ltrace works) versus NOW (ltrace doesn't).

There is a little bit more discussion (but no resolution) here:

https://bugzilla.redhat.com/show_bug.cgi?id=1333481

ltrace does not show sin() in the output

This is because your sin call is a constant value and gcc optimizes it out (even when compiling with -O0 and without -lm). This is the result of running disass main in gdb:

   0x0000000000400580 <+0>:     push   %rbp
0x0000000000400581 <+1>: mov %rsp,%rbp
0x0000000000400584 <+4>: sub $0x10,%rsp
0x0000000000400588 <+8>: mov 0xee(%rip),%eax # 0x40067c
0x000000000040058e <+14>: mov %eax,-0x4(%rbp)
0x0000000000400591 <+17>: mov $0x400660,%edi
0x0000000000400596 <+22>: callq 0x400450 <puts@plt>
0x000000000040059b <+27>: mov 0xdf(%rip),%eax # 0x400680
0x00000000004005a1 <+33>: mov %eax,-0x4(%rbp)
0x00000000004005a4 <+36>: movss -0x4(%rbp),%xmm0
0x00000000004005a9 <+41>: cvtps2pd %xmm0,%xmm0
0x00000000004005ac <+44>: mov $0x40066e,%edi
0x00000000004005b1 <+49>: mov $0x1,%eax
0x00000000004005b6 <+54>: callq 0x400460 <printf@plt>
0x00000000004005bb <+59>: mov $0x0,%eax
0x00000000004005c0 <+64>: leaveq
0x00000000004005c1 <+65>: retq

There is no call for sin here.

Changing your code to read:

#include<stdio.h>
#include<math.h>

int main()
{
float x, y;
scanf("%f", &x);
y=sin(x);
printf("sin(%f)=%f\n", x, y);
return 0;
}

will make you need -lm when compiling:

$ gcc -Wall -Wextra -O0 -g 1.c -lm

and now you'll see this disassembled output:

   ...
0x00000000004006c9 <+25>: callq 0x4005b0 <__isoc99_scanf@plt>
0x00000000004006ce <+30>: movss -0x8(%rbp),%xmm0
0x00000000004006d3 <+35>: unpcklps %xmm0,%xmm0
0x00000000004006d6 <+38>: cvtps2pd %xmm0,%xmm0
0x00000000004006d9 <+41>: callq 0x4005a0 <sin@plt>
...

and the call in ltrace:

__libc_start_main(0x4006b0, 1, 0x7fffd25ecff8, 0x400720 <unfinished ...>
__isoc99_scanf(0x4007b0, 0x7fffd25ecf08, 0x7fffd25ed008, 0x400720) = 1
sin(0x7fffd25ec920, 0x7fa1a6388a20, 1, 16) = 0x7fa1a643b780
printf("sin(%f)=%f\n", 3.000000, 0.141120sin(3.000000) =0.141120
) = 23
+++ exited (status 0) +++

Alternative to ltrace that works on binaries linked with `-z now`?

You can use uftrace utility written by Namhyung
Kim. It's available as a package
in Ubuntu although I built
the code from master branch manually to make sure I use the newest
vanilla version. Example main.c:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
puts("Hello World");

return EXIT_SUCCESS;
}

Build with -z now:

gcc -O2 main.c -z now -o main

ltrace doesn't work:

$ ltrace ./main
Hello World
+++ exited (status 0) +++

But uftrace does:

$ LD_LIBRARY_PATH=~/uftrace/libmcount ~/uftrace/uftrace -a --force ./main
Hello World
# DURATION TID FUNCTION
58.231 us [ 16283] | puts("Hello World") = 12;

See this thread on project's site on Github: tracing library calls
even if it has no PLT #592.

How to trace dynamically loaded library calls with ltrace

You need to add a special flag -x pattern to force tracing of symbols in dlopen-ed libraries (the easiest would be -x '*', see @nayana's answer for more details.)

Older versions of ltrace do not include the relevant patch from https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=537781 (follow link to timetobleed.com) so they can't trace dlopen-ed libs.

Line Number Info in ltrace and strace tools

You may be able to use the -i option (to output the instruction pointer at the time of the call) in strace and ltrace, combined with addr2line to resolve the calls to lines of code.



Related Topics



Leave a reply



Submit