Profiling an Application

You can select a topic from this diagram:

Glossary What's New Utilities Used by the IDE Getting System Information Using Code Coverage Common Wizards Reference Preparing Your Target Developing Photon Applications Developing C/C++ Programs Where Files Are Stored Building OS and Flash Images Migrating to the 6.3 Release Tutorials IDE Concepts About This Guide Analyzing Your System With Kernel Tracing Profiling an Application Finding Memory Errors Debugging Programs Managing Source Code Launch Configurations Reference

Workflow diagram with profiler chapter highlighted


This chapter shows you how to use the application profiler.

In this chapter:

Introducing the Application Profiler

The QNX Application Profiler perspective lets you examine the overall performance of programs, no matter how large or complex, without following the source one line at a time. Whereas a debugger helps you find errors in your code, the QNX Application Profiler helps you pinpoint "sluggish" areas of your code that could run more efficiently.


QNX Application Profiler perspective


The QNX Application Profiler perspective.

Types of profiling

The QNX Application Profiler lets you perform:

Statistical profiling

The QNX Application Profiler takes "snapshots" of your program's execution position every millisecond and records the current address being executed. By sampling the execution position at regular intervals, the tool quickly builds a summary of where the system is spending its time in your code.

With statistical profiling, you don't need to use instrumentation, change your code, or do any special compilation. The tool profiles your programs unintrusively, so it doesn't bias the information it's collecting.

Note, however, that the results are subject to statistical inaccuracy because the tool works by sampling. Therefore, the longer a program runs, the more accurate the results.

Instrumented profiling

If you build your executables with profiling enabled, the QNX Application Profiler can provide call-pair information (i.e. which functions called which). When you build a program with profiling enabled, the compiler inserts snippets of code into your functions in order to report the addresses of the called and calling functions. As your program runs, the tool produces an exact count for every call pair.

Postmortem profiling

The IDE lets you examine profiling information from a gmon.out file produced by an instrumented application. The tool gives you all the information you'd get from the traditional gprof tool, but in graphical form. You can examine gmon.out files created by your programs, whether you built them using the IDE or the qcc -p command. For more on the gprof utility, go to www.gnu.org; for qcc, see the Utilities Reference.

Profiling your programs

Whether you plan to do profiling in real time or postmortem (using a gmon.out file), you should build your programs with profiling enabled before starting a profiling session.

This section includes these topics:


Note: If you already have a gmon.out file, you're ready to start a postmortem profiling session.

Building a program for profiling

Although you can profile any program, you'll get the most useful results by profiling executables built for debugging and profiling. The debug information lets the IDE correlate executable code and individual lines of source; the profiling information reports call-pair data.


Note: Profiling is handled by functions in libc; be sure to check our website for libc updates from time to time.

This table shows the application-profiling features that are possible with the various build variants:

Feature Release version Debug version Release v. & profiling Debug v. & profiling
Call pairs No No Yes Yes
Statistical sampling Yes (function level) Yes Yes (function level) Yes
Line profiling No Yes No Yes
Postmortem profiling No No Yes Yes

To build executables with debug information and profiling enabled:

  1. In the C/C++ Projects view, right-click your project and select Properties.
  2. In the left pane, select QNX C/C++ Project.
  3. In the right pane, select the Options tab.
  4. Check the Build with Profiling option:

    Properties dialog

  5. Select the Build Variants tab and check the Debug variant for your targets.

    Note: The QNX Application Profiler uses the information in the debuggable executables to correlate lines of code in your executable and the source code. To maximize the information you get while profiling, use executables with debug information for both running and debugging.

  6. Click Apply.
  7. Click OK.
  8. Rebuild your project.

Note: To build a Standard Make C/C++ project for profiling, compile and link using the -p option. For example, your Makefile might have a line like this:
CFLAGS=-p CXXFLAGS=-p LDFLAGS=-p

Running and profiling a process

To run and profile a process, with qconn on the target:

  1. Create a QNX Application launch configuration for an executable with debug information as you normally would, but don't click OK. You may choose either a Run or a Debug session.
  2. On the launcher, click the Tools tab.
  3. Click Add/Delete Tool. The Select tools to support dialog appears.
  4. Enable the Application Profiler tool.
  5. Click OK.
  6. On the launcher, click the Application Profiler tab:

    Launcher; tools tab; Profiler

  7. Fill in these fields:
    Profiler update interval (ms)
    Use this option to control how often the Profiler polls for data. A low setting causes continuous (but low) network traffic and fast refresh rates. A high setting causes larger network data bursts and may cause higher memory usage on the target because the target must buffer the data. The default setting of 1000 should suffice.
    Shared library paths
    The IDE doesn't know the location of your shared library paths, so you must specify the directory containing any libraries that you wish to profile.
    Switch to this tool's perspective on launch.
    Check this option to automatically switch to the QNX Application Profiler perspective when this launch configuration is used.
  8. If you want the IDE to automatically change to the QNX Application Profiler perspective when you run or debug, check the Switch to this tool's perspective on launch box.
  9. Click Apply.
  10. Click Run or Debug. The IDE starts your program and profiles it.

Note: To produce full profiling information with function timing data, you need to run the application as root. This is the case when running through qconn.

If you run the application as a normal user, the profiler can generate only call-chain information.


Profiling a running process

To profile a process that's already running on your target:


Note: When you profile a running process, you can't use the Console view in the IDE to interact with this process. If your running process requires user input through the Console view, use a shell to interact with the process.

  1. While the application is running, open the Launch Configurations dialog by choosing Run-->Debug... from the menu.
  2. Select C/C++ QNX Attach to Process w/QConn (IP) in the list on the left.
  3. Click the New button to create a new attach-to-process configuration.
  4. Configure things as you normally would for launching the application with debugging.
  5. On the Tools tab, click Add/Delete Tool.... The Tools Selection dialog appears.
  6. Enable the Application Profiler tool, then click OK.
  7. On the launcher, click the Application Profiler tab:

    Launcher; tools tab; Profiler

  8. Fill in these fields:
    Profiler update interval (ms)
    You use this option to control how often the Profiler polls for data. A low setting causes continuous (but low) network traffic and fast refresh rates. A high setting causes larger network data bursts and may cause higher memory usage on the target because the target must buffer the data. The default setting of 1000 should suffice.
    Shared library paths
    The IDE doesn't know the location of your shared library paths, so you must specify the directory containing any libraries that you wish to profile. For a list of the library paths that are automatically included in the search path, see the appendix Where Files Are Stored.
    Switch to this tool's perspective on launch.
    Check this to automatically switch to the QNX Application Profiler perspective when using this launcher.
  9. Click Apply, and then click Debug. The Select Process dialog is displayed, showing all of the currently running processes:

    Select Process dialog

  10. Select the process you want to profile, then click OK.

Note: Your running application won't generate call-pair information unless you ran it with the QCONN_PROFILER environment variable set to /dev/profiler.

If you're launching the application from the IDE, add QCONN_PROFILER to the Environment tab of the launch configuration's Properties dialog.

If you're running the application from the command line, you can simply add QCONN_PROFILER to your shell environment, or the application's command-line:

QCONN_PROFILER=/dev/profiler ./appname

Postmortem profiling

The IDE lets you profile your program after it terminates, using the traditional gmon.out file. Postmortem profiling doesn't provide as much information as profiling a running process:

Profiling a gmon.out file involves three basic steps:

Gathering profiling information

The IDE lets you store your profiling information in the directory of your choice using the PROFDIR environment variable.

To gather profiling information:

  1. Create a launch configuration for a debuggable executable as you normally would, but don't click Run or Debug.

    Note: You must have the QNX Application Profiler tool disabled in your launch configuration.

  2. Select the Environment tab.
  3. Click New.
  4. In the Name field, type PROFDIR.
  5. In the Value field, enter a valid path to a directory on your target machine.
  6. Click OK.
  7. Run your program. When your program exits successfully, it creates a new file in the directory you specified. The filename format is pid.fileName (e.g. 3047466.helloworld_g). This is the gmon.out profiler data file.

Importing a gmon.out file

You can bring existing gmon.out files that you created outside the IDE into your workspace from your target system.

To import a gmon.out file into your workspace:

  1. Open the Target File System Navigator view (Window-->Show View-->Other...-->QNX Targets-->Target File System Navigator).
  2. In the Target File System Navigator view, right-click your file and select Copy to...-->Workspace. The Select target folder dialog appears.
  3. Select the project related to your program.
  4. Click OK.
  5. In the C/C++ Projects view, right-click the file you imported into your workspace and select Rename.
  6. Enter gmon.out (or gmon.out.n, where n is any numeric character). The IDE renames your file.

Starting a postmortem profiling session

To start the postmortem profiling session:

  1. In the C/C++ Projects view, right-click your gmon.out file and select Open in QNX Application Profiler. The Program Selection dialog appears.
  2. Select the program that generated the gmon.out file.
  3. Click OK. You can now profile your program in the QNX Application Profiler perspective.

Controlling your profiling sessions

The Application Profiler view (Window-->Show View-->Other...-->QNX Application Profiler-->Application Profiler) lets you control multiple profiling sessions simultaneously. You can:

Profiler view

The Application Profiler view displays the following as a hierarchical tree for each profiling session:

Session item Description Possible icons
Launch instance Launch configuration name and launch type (e.g. prof201 [C/C++ QNX QConn (IP)]) Icon: Running Launch
Profiled program Project name and start time (e.g. prof201 on localhost pid 4468773 (3/4/03 12:41 PM)) Icon: Running Process Icon: Terminated Process
Application Profiler instance Program name and target computer (e.g. Application Profiler Attached to: prof201 <4468773> on 10.12.3.200) Icon: QNX Application Profiler tool
Executable   Icon: Executable
Shared libraries   Icon: Library
DLLs   Icon: DLL
Unknown   Icon: Unknown
To choose which executable or library to display information for in the QNX Application Profiler perspective:
In the Application Profiler view, click one of the following:

To terminate an application running on a target:

  1. In the Application Profiler view, select a launch configuration.
  2. Click the Terminate button (Icon: Terminate) in the view's title bar.

    Note: To clear old launch listings from this view, click the Remove All Terminated Launches button (Icon: Remove All Terminated Launches).

To disconnect from an application running on a target:

  1. In the Application Profiler view, select a running profiler.
  2. Click the Disconnect button (Icon: Disconnect) in the view's title bar.

    Note: To clear old launch listings from this view, click the Remove All Terminated Launches button (Icon: Remove All Terminated Launches).

Understanding your profiling data

For each item you select in the Application Profiler view, other views within the QNX Application Profiler perspective display the profiling information for that item:

This view: Shows:
Application Profiler Usage by line
Sampling Information Usage by function
Thread Processor Usage Usage by thread
Call Information Call counts

Usage by line

The Application Profiler editor lets you see the amount of time your program spends on each line of code and in each function.

To open the editor:

  1. Launch a profile session for a debuggable (i.e. _g) executable.
  2. In the Application Profiler view, select your program by selecting an Application Profiler instance (Icon: QNX Application Profiler tool) or an executable (Icon: Executable).
  3. In the Sampling Information or Call Information view, double-click a function that you have the source for. The IDE opens the corresponding source file in the Application Profiler editor:

    Application Profiler editor


Note: You may get incorrect profiling information if you change your source after compiling, because the Application Profiler editor relies on the line information provided by the debuggable version of your code.

The Application Profiler editor displays a bar graph on the left side. The bars are color coded:

Green
CPU time spent within the function as a percentage of the program's total CPU time. The green bar appears on the first line of executable code in the function.
Orange
CPU time spent on a line of code as a percentage of the program's total CPU time. Within a function, the lengths of the orange bars add up to the length of the green bar.
Blue
CPU time spent on a line of code as a percentage of the function's total CPU time. Within a function, the sum of all the blue bars spans the width of the editor's margin.

To view quantitative profiling values:
In the Application Profiler editor, let the pointer hover over a colored bar. The CPU usage appears, displayed as a percentage and a time:

Application Profiler editor; hovering

Usage by function

The Sampling Information view shows a flat profile of the item that's currently selected in the Application Profiler view. You can examine profiling information for programs, shared libraries, and DLLs:

Sampling Information view

The view lists all the functions called in the selected item. For each function, this view displays:

If you select a program compiled for profiling, the view also displays:

To see your function usage:

  1. Launch a profile session for a profiling-enabled (i.e. _g) executable.
  2. In the Application Profiler view, select your program by selecting an Application Profiler instance (Icon: QNX Application  Profiler tool) or any subordinate line. The Sampling Information view displays profiling information for your selection.
To reset the counters in the Time since last reset(s) column:
Select the Use/Calls since last reset item from the dropdown menu in the title bar for the Sampling Information view.

Usage by thread

The Thread Processor Usage view displays the CPU usage (in seconds and as a percentage of your program's total time) for each thread of the item that's currently selected in the Application Profiler view:

Thread Processor Usage view

You can use this information to:

To see your thread usage:

  1. Launch a profile session for a profiling-enabled (i.e. _g) executable.
  2. In the Application Profiler view, select your program by selecting an Application Profiler instance (Icon: QNX Application  Profiler tool) or any subordinate line. The Thread Processor Usage view displays profiling information for your selection.

Call counts

For the item that's currently selected in the Application Profiler view, the Call Information view shows your call counts in three panes:

To display your call counts:

  1. Launch a profile session for a profiling-enabled (i.e. _g) executable.
  2. In the Application Profiler view, select your program by selecting an Application Profiler instance (Icon: QNX Application Profiler tool) or any subordinate line. The Call Information view displays profiling information for your selection:

    Call Information view

Call Pairs pane

The Call Pairs pane shows you where every function was called from as well as the call-pair count, i.e. the number of times each function called every other function.

Call Graph pane

The Call Graph pane shows you a graph of the function calls. Your selected function appears in the middle, in blue. On the left, in yellow, are all the functions that called your function. On the right, also in yellow, are all the functions that your function called.

To see the calls to and from a function:
Click a function in:

Note: You can display the call graph only for functions that were compiled with profiling enabled.

Call Pair Details pane

The Call Pair Details pane shows the information about the function you've selected in the Call Graph pane. The Caller and Call Count columns show the number of times each function called the function you've selected.

The Called and Called Count columns show the number of times your selected function called other functions. This pane shows only the functions that were compiled with profiling. For example, it doesn't show calls to functions, such as printf(), in the C library.