profiling gcc code on windows ce

this is a description of how to use the gcc profiling feature with a gcc-arm crosscompiler, in a non-clib environment. ( being windows CE )

Code compiled with gcc option '-pg' every function is instrumented with a call to mcount

When linking this code into a windows-ce binary, this will not work, since it expects some startup code to be present in the crt0.obj ( where all startup code resides ).

I wrote my own implementation of the profiling code (mcount.S), the startup/finish code (mcountinit.c) and a perl script to process the output (gmon.pl). You can find all sources here

Statistics are kept per function-call [ = from where and to which function ]. for this to work, your code has to be compiled without -fomit-frame-pointer.

This code uses the 'ostimer' register in the sa11xx chips, to get accurate timing information. on the xda this register is mapped to 0xa9000010, this may be different on other platforms. This timer wraps approximately every 18 minutes. my code does not attempt to recognise this. so either fix the code, or do not run profiling tests for more than 18 minutes.

how to use

1. code

Before the code you want to profile is executed, insert a call to monstartup with as parameters the maximum call-depth to be tracked, and the maximum number of function calls to be tracked.

Before terminating the application, call monexit.

2. compiling

Compile your gcc code with -pg and without -fomit-frame-pointer
Link it into an executable, and keep the .map file. it is needed later to resolve symbols.

3. run

Execute your code. make sure that before the application terminates monexit is called, otherwise no profiling data will be saved.

4. get results

Copy the 'gmon.out' file from your device, and run it through the perl script:
	perl gmon.pl gmon.out yourapp.map

profiling with the microsoft compiler

clarm has 2 commandline options governing code instrumentation:
  • /callcap - adds calls to CAP_Enter_Function(const char *funcname) and CAP_Exit_Function(const char *funcname) to the start and end of each function.
  • /fastcap - adds calls to CAP_Start_Profiling(const char *caller, const char *funcname) and CAP_End_Profiling(const char *caller) before and after the call to each function.

    for the x86 compiler:

  • /GH /Gh - adds calls to _penter() and _pexit() at the start and exit of each function.