Currently, the NaCl loader copies code from nexe files into memory so that changes to the file are not reflected in memory. This is especially important since the code is only validated once, and not every time the file changes. However, this copying can confuse tools like profilers, which do not know how these memory addresses map to the code in the original executable. The good news is, it is still possible to use tools like profilers if there is a tool to map the sampled instruction addresses to functions. There is an experimental script in the native client repository that will do this mapping for you, when using oprofile. Eventually, we will have a cleaner solution.
Limitations: This does not work for the x86-32 sandbox and has not yet been tested with ARM (please update this if it is found to work =)). Also, this does not work with the oprofile "--callgraph" option. It has only been tested with static linking and not dynamic linking with glibc.
This should work with nexes that are loaded through chrome as well as the command-line tool "sel_ldr".
This will print the top 30 most CPU intensive functions in the untrusted sandbox (the anon region) along with samples in trusted code (e.g., chrome). The script will also generate an annotated output file (test_nacl64.nexe.annotated in the example) that contains the disassembly along with annotations such as:
where 265, is the number of samples taken by oprofile for that instruction.
This script can be found in the native client svn repo: http://src.chromium.org/viewvc/native_client/trunk/src/native_client/tools/process_oprofile_x86_64.py?content-type=text%2Fplain.