Introductionnacl_profile.py is a tool for profiling NaCl modules on 64-bit Windows. It is a thin wrapper around AMD CodeAnalyst. CodeAnalyst does the actual profiling, and nacl_profile.py maps the samples in the NaCl sandbox to symbols in the nexe files and the IRT (NaCl Integrated RunTime).
nacl_profile could also be made to work on Linux (using CodeAnalyst) and Mac (using Shark) with minor modifications. For now, developers on Linux can use oprofile for NaCl profiling. If you’d like nacl_profile support on Linux or Mac, let the NaCl team know on the Native Client discussion group. That’s also a great place to ask questions about nacl_profile. Found a bug? Please report it in our bug tracker.
To enable nacl_profile to get symbol information (information about what functions are being called), you should make sure to point it to a non-stripped nexe. To profile my_app_x86_64.nexe navigate to your web app, so that my_app_x86_64.nexe is already running in Chrome, and execute the following in a command prompt:
python nacl_profile.py --nexe_file=my_app_x86_64.nexe
This will start the profiler, profile the system for 20 seconds, and print three summaries to the console: (1) a system-wide process top 20, (2) a system-wide module top 20, and (3) a Native Client function top 30:
Samples % PID Process Name
-------- -------- -------- ------------------------
3020338 92.53 0 System Idle
184477 5.65 936 chrome.exe
26361 0.80 4268 nacl64.exe
19073 0.58 4 unknown module pid(4)
Samples % Module Name
-------- -------- -------------------------
3018223 92.47 ntoskrnl.exe
148113 4.53 ntdll.dll
24052 0.73 unknown module pid (4268)
14695 0.45 libglesv2.dll
12924 0.39 ntoskrnl.exe
Probable nexe process ids: ['4268']
% Address Symbol
----- ------------- -----------------------------------------------------------
18.6 0x00c00024460 Tentacle::draw(unsigned long long, mat4 const&, mat4 const&
, mat4 const&)
16.4 0x00c000201e0 mat4::operator*(mat4 const&) const
8.0 0x00c000ecd20 __kernel_sinf
6.8 0x00c000ebce0 __kernel_cosf
6.1 0x00c0fc322a0 gpu::CommandBufferHelper::WaitForAvailableEntries(int)
Want more than the top 30? Use --top=n or simply go --top=all to get everything.
In the list of NaCl functions you are likely to see lines with an address of the form 0xc0fchhhh, e.g.,
These addresses are inside the Native Client IRT. To get symbol information for them, point nacl_profile to the nexe for the IRT (nacl_irt_x86_64.nexe for 64-bit). You can find the IRT in the directory where chrome.exe resides or a subdirectory typically named after the Chrome version, e.g., 15.0.874.100\.
To have nacl_profile lookup the symbols corresponding to these addresses, use the --irt_file argument:
python nacl_profile.py --nexe_file=my_app_x86_64.nexe ^
Sometimes it is convenient, e.g., from within an IDE like Visual Studio or Eclipse, to start a NaCl process with Chrome, profile it, and exit when done. This can be achieved by using --delay=n --command_line=cmd, which runs cmd, waits for n seconds, profiles for 20 seconds, and exits. E.g.,
We recommend binding a key in your IDE to this command, so that you can profile the application with one keystroke. E.g., in Visual Studio you can set up a build configuration to execute this when you hit Ctrl-F5 (Start Without Debugging).
The profiling tools assumes a standard inner sandbox offset of 0xc00000000. If this is not the case, the --offset=0xhhhhhhhh option should be used. To find the offset connect a debugger to the running nexe and read the contents of register r15.
Sometimes, e.g., when developing applications that render 3D graphics, it is important to know if there are bottlenecks elsewhere in the system, perhaps because the NaCl process is issuing more glDraw calls than the graphics stack on the machine can handle.
By default nacl_profile (via CodeAanalyst) collects system-wide information that can be examined in CodeAnalyst. After running nacl_profile, you’ll see a .caw file, e.g., my_app_x86_64.caw. Open this file in CodeAnalyst to examine the profiling information for all non-NaCl sandboxed processes. Your nexe will typically show up as “unknown module pid (n)”, but CodeAnalyst will not be able lookup its symbols because of the sandbox offset.
nacl_profile overwrites the data from previous runs without prompting. If you want to keep the data from a particular run, put the .caw file, the .tbp.dir directory, and optionally the raw .prd file somewhere safe before running nacl_profile again.
If you want to see what Chrome is doing, you first need to get the symbols. There are at least two options:
Here is a screenshot showing the files for Chromium used in the above set-up. Notice the .pdb files:
To make profiling and analyzing both NaCl and other processes easier, nacl_profile provides the flag --run_codeanalyst, which after profiling will launch CodeAnalyst in addition to printing the usual profiling information for the NaCl module:
python nacl_profile.py --nexe_file=my_app_x86_64.nexe ^
nacl_profile support several additional command line options, e.g,. to disable system summaries, output CSV results, and not collapsing individual samples into function buckets. To see the complete summary run the following:
c:\...\> python nacl_profile.py --help
nacl_profile.py is a tool for profiling NaCl modules on 64-bit Windows.
-h, --help show this help message and exit
Optional command to run before profiling (e.g.,
Path to the unstripped .nexe file being run
--irt_file=IRT_FILE Path to the unstripped IRT being used
--csv Output results (NaCl only) in comma-separated format
--out=OUTPUT Output file.
--offset=OFFSET Sandbox memory offset for NaCl.
--delay=DELAY Delay in seconds before starting profiler.
--top=TOP Number of lines to print (default 30) or --top=all for
--no_collapse Don't collapse profiler samples into a single sample
for each function.
--run_codeanalyst Launch CodeAnalyst to see system-wide non-NaCl data
--no_system_data Don't print system-wide module/process data. If you
don't print the data, you can still see it by opening
the .caw file in CodeAnalyst.
If you feel you've run into a performance issue in Chrome or Native Client, you can report it by creating an issue. Please be sure to include