Q:

Which function is called in a C program?

I am trying to figure out which exact function is called (from which include file) when I call a library function. 
So, I have this program, 
#include <stdio.h>
#include <math.h>

int twice(int input) {
  int output;
  output = input * 2;
  return output;
}

int main(int argc, char **argv) {
  printf("Hello World and %f\n", sin(1));
  printf("Output: %d\n", twice(3));
  printf("Here is the end of the program... %d\n", 3);
}

I want to see which printf is called. (I know in this case, it is the one in stdio.h, but this is just an example.) 
I compile the file: 
g++ -g test.cpp

and then do dump the assembly code
objdump --source a.out > test.objdump

In the test.objdump, I see lines like 
int main(int argc, char **argv) {
  400528: 55                    push   %rbp
  400529: 48 89 e5              mov    %rsp,%rbp
  40052c: 48 83 ec 10           sub    $0x10,%rsp
  400530: 89 7d fc              mov    %edi,-0x4(%rbp)
  400533: 48 89 75 f0           mov    %rsi,-0x10(%rbp)
  printf("Hello World and %f\n", sin(1));
  400537: f2 0f 10 05 91 01 00  movsd  0x191(%rip),%xmm0   #4006d0<__dso_handle+0x50>
  40053e: 00
  40053f: bf 88 06 40 00        mov    $0x400688,%edi
  400544: b8 01 00 00 00        mov    $0x1,%eax
  400549: e8 c2 fe ff ff        callq  400410 <printf@plt>
  printf("Output: %d\n", twice(3));
  40054e: bf 03 00 00 00        mov    $0x3,%edi
  400553: e8 bc ff ff ff        callq  400514 <_Z5twicei>
  400558: 89 c6                 mov    %eax,%esi
  40055a: bf 9c 06 40 00        mov    $0x40069c,%edi
  40055f: b8 00 00 00 00        mov    $0x0,%eax
  400564: e8 a7 fe ff ff        callq  400410 <printf@plt>
  printf("Here is the end of the program... %d\n", 3);
  400569: be 03 00 00 00        mov    $0x3,%esi
  40056e: bf a8 06 40 00        mov    $0x4006a8,%edi
  400573: b8 00 00 00 00        mov    $0x0,%eax
  400578: e8 93 fe ff ff        callq  400410 <printf@plt>
  40057d: b8 00 00 00 00        mov    $0x0,%eax
}

It seems like the address of the printf function is given in callq line: 400410. But when I do
addr2line -e a.out 0x400410 

(I tried 400410 without 0x too), I get
??:0

which does not give me the location of the printf function. Can somebody point out the error in my process. Is there some option to g++ I am not passing?
Really appreciate the help. Thank you!  

A:

You're compiling your code into object code, and then dumping the assembly code from the object code. At that point, the code has not been linked together by the linker, and so printf is merely a symbol in the Procedure Linkage Table. Only when the program has been linked will that definition appear.
EDIT: On second glance at your compiler options, I see the executable is being linked together. If you do have debugging symbols built in, you may need to specify which section you wish to use with addr2line.
As for using printf, I believe addr2line can only find the definitions of functions local to your executable, not function defined by external libraries. From test.cpp's perspective, printf exists outside of itself and cannot have a line under which it was defined, because that will only be recorded by the library being linked. If that library (glibc in this case) was not compiled as a debugging build, you cannot know what file and line number it was defined on.

