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
Where Is Hardware Timer Interrupt
Merge PDF Files with Numerical Sort
Xdotool Commands Bound to Key Shortcuts Doesnot Work
Not Authorized for Query on Admin.System.Namespaces on Mongodb
@Reboot Is Not Working in Cron
How to Get Started Writing a Compositing Wm
How to Find or Calculate a Linux Process's Page Table Size and Other Kernel Accounting
How to Setup Oracle Odbc Drivers on Rhel 6/Linux
The Return Code from 'Grep' Is Not as Expected on Linux
Error: Ld.So: Object Ld_Preload Cannot Be Preloaded: Ignored
Difference Between Patch and Diff Files
Bash Script Read All the Files in Directory
Centos Error - Sudo: Effective Uid Is Not 0, Is Sudo Installed Setuid Root
Cmd 2>&1 > Log VS Cmd > Log 2>&1