How to build an executable with profiling?

Hans Ottevanger hansot at iae.nl
Fri Jan 21 16:42:08 UTC 2011


On 01/20/11 19:54, Roman Divacky wrote:
>
> ok, I sat down and implemented what Hans Ottevanger told me to do :)
>
>          http://lev.vlakno.cz/~rdivacky/clang-gprof.patch
>

I have installed clang and the patch you provided in the following way:

cd /home/hans
mkdir clang
export PATH=/home/hans/clang/bin:$PATH
mkdir testllvm
cd testllvm
mkdir build
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
cd llvm/tools
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
cd clang/
patch < /tmp/clang-gprof.patch 2>&1 | tee /tmp/log
cd ../../..
cd build
../llvm/configure --prefix=$HOME/clang
gmake -j 4
gmake install

> This patch does three things:
>
> 1) emits "call .mcount" at the begining of every function body
>

The differences on i386 between profiled and non-profiled code are not 
as obvious as with gcc (using diff on assembly output), but on first 
inspection it looks correct.

> 2) changes the driver to link in gcrt1.o instead of crt1.o
>
> 3) changes all -lfoo to -lfoo_p except when the foo ends with _s in
>     the linker invocation
>

With gcc the libraries specified by the caller are left alone, maybe for 
a good reason (more control over what really gets linked).

On amd64 (9.0-CURRENT r217444) calling

gcc -v -O2 -o tf tf.c -lm

yields

/usr/bin/ld --eh-frame-hdr -V -dynamic-linker /libexec/ld-elf.so.1 -o tf 
/usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/lib 
-L/usr/lib /var/tmp//ccnOsNq4.o -lm -lgcc --as-needed -lgcc_s 
--no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed 
/usr/lib/crtend.o /usr/lib/crtn.o

and

gcc -v -pg -O2 -o tf tf.c -lm

results in

/usr/bin/ld --eh-frame-hdr -V -dynamic-linker /libexec/ld-elf.so.1 -o tf 
/usr/lib/gcrt1.o /usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/lib 
-L/usr/lib /var/tmp//cc9Btbiv.o -lm -lgcc_p -lgcc_eh_p -lc_p -lgcc_p 
-lgcc_eh_p /usr/lib/crtend.o /usr/lib/crtn.o

Maybe it is wise to follow the gcc implementation here.

> I am not sure that I did the right thing, especially in (3). Anyway,
> the patch works for me (ie. produces a.out.gmon that seems to contain
> meaningful data).
>
> I would appreciate if you guys could test and review this. Letting me
> know if this is correct.
>

On both my systems (i386 and amd64) something goes severely wrong when 
linking several objects (all compiled with -pg, this is amd64):

clang -v -pg -O2 -Wall -o test test.o angle.o apsis.o error.o minmax.o 
qags.o  qext.o qk21.o sort.o timint.o zero.o vmol.o -lm
clang version 2.9 (trunk 123975)
Target: x86_64-unknown-freebsd9.0
Thread model: posix
  "/usr/bin/ld" --eh-frame-hdr -dynamic-linker /libexec/ld-elf.so.1 -o 
test /usr/lib/gcrt1.o /usr/lib/crti.o /usr/lib/crtbegin.o test.o angle.o 
apsis.o error.o minmax.o qags.o qext.o qk21.o sort.o timint.o zero.o 
vmol.o ld /usr/bin/ld --as-needed -lgcc_s --no-as-needed ld /usr/bin/ld 
--as-needed -lgcc_s --no-as-needed /usr/lib/crtend.o /usr/lib/crtn.o
/usr/bin/ld: ld: No such file: No such file or directory
clang: error: linker command failed with exit code 1 (use -v to see
invocation)

Polishing the linker invocation a bit as follows

"/usr/bin/ld" --eh-frame-hdr -dynamic-linker /libexec/ld-elf.so.1 -o 
test /usr/lib/gcrt1.o /usr/lib/crti.o /usr/lib/crtbegin.o test.o angle.o 
apsis.o error.o minmax.o qags.o qext.o qk21.o sort.o timint.o zero.o 
vmol.o -lm_p --as-needed -lgcc_s -lc_p --no-as-needed --as-needed 
-lgcc_s --no-as-needed /usr/lib/crtend.o /usr/lib/crtn.o

yields a profiled executable. running gprof on the test.gmon file gives 
results that are very similar to those when compiling with gcc: the 
number of calls is identical and the time spent is comparable.

Perhaps the invocation of the linker still needs some work (or I must 
redo my installation) but anyhow it looks like a good job. Thanks!

Kind regards,

Hans


More information about the freebsd-toolchain mailing list