Wednesday, August 3, 2016

Google profiler for Performance and Memory Analysis



Goolge profiler tool instalation for Ubuntu:
sudo apt-get install google-perftools

Analyse memory consumption:
LD_PRELOAD=/usr/lib/libtcmalloc.so.0.0.0 HEAPPROFILE=gpt-heapprofile.log ./your-program

To analyse mmp please set HEAP_PROFILE_MMAP environment variable to TRUE.

Performance analysis:
LD_PRELOAD=/usr/lib/libprofiler.so.0.4.5 CPUPROFILE=/home/amd/gst-log gst-launch-1.0 -f filesrc location= ./1080p_H264.mp4 ! qtdemux ! h264parse ! vaapidecode ! filesink location= test.yuv


Convert Data to pdf format:
google-pprof --pdf  /usr/bin/python /home/amd/gst-log >  profile_output.pdf

Text output can be obtained by typing:
google-pprof --text /usr/bin/python /home/amd/gst-log > profiling_output.txt

The file "/home/amd/gst-log" can also be analyzed with some specific graphical interfaces like "kcachegrind".

To prepare de data for kcachegrind type:
   google-pprof --callgrind /usr/bin/python /home/amd/gst-log > profiling_kcachegrind.txt
 
visualize the information use kcachegrind:
   kcachegrind profiling_kcachegrind.txt &

Example view of Performance Analysis:





References:
http://goog-perftools.sourceforge.net/doc/cpu_profiler.html

http://alexott.net/en/writings/prog-checking/GooglePT.html

http://kratos-wiki.cimne.upc.edu/index.php/How_to_Profile_an_application_(using_google-perftools)

http://stackoverflow.com/questions/10874308/how-to-use-google-perf-tools




Tuesday, August 2, 2016

Debugging using gdb Tracepoints


Trace command: 
The trace command is very similar to the break command. Its argument can be a source line, a function name, or an address in the target program.

The trace command defines a tracepoint, which is a point in the target program where the debugger will briefly stop, collect some data, and then allow the program
to continue.

Setting a tracepoint or changing its commands doesn't take effect until the next tstart command.

(gdb) trace foo.c:121    // a source file and line number

(gdb) trace +2           // 2 lines forward

(gdb) trace my_function  // first source line of function

(gdb) trace *my_function // EXACT start address of function

(gdb) trace *0x2117c4    // an address

(gdb) delete trace 1 2 3 // remove three tracepoints

(gdb) delete trace       // remove all tracepoints

(gdb) info trace        // trace points info


Starting and Stopping Trace Experiment:

tstart : It starts the trace experiment, and begins collecting data.

tstop :  It ends the trace experiment, and stops collecting data.

tstatus : This command displays the status of the current trace data collection.


Enable and Disable Tracepoints:

disable tracepoint [num] : Disable tracepoint num, or all tracepoints if no argument num is given.

enable tracepoint [num] : Enable tracepoint num, or all tracepoints.


Tracepoint Passcounts:

passcount [n [num]] : Set the passcount of a tracepoint. The passcount is a way to automatically stop a trace experiment. If a tracepoint's passcount is n,  then the trace experiment will be automatically stopped on the n'th time that tracepoint is hit. If the tracepoint number num is not specified, the passcount command sets the passcount of the most recently defined tracepoint. If no passcount is given, the trace experiment will run until stopped explicitly by the user.

Examples:
(gdb) passcount 5 2 // Stop on the 5th execution of  tracepoint 2

(gdb) passcount 12  // Stop on the 12th execution of the most recently defined tracepoint.
(gdb) trace foo
(gdb) pass 3
(gdb) trace bar
(gdb) pass 2
(gdb) trace baz
(gdb) pass 1        // Stop tracing when foo has been
                           // executed 3 times OR when bar has
                           // been executed 2 times
                           // OR when baz has been executed 1 time.


Tracepoint Action Lists:

actions [num] : This command will prompt for a list of actions to be taken when the tracepoint is hit. If the tracepoint number num is not specified, this command sets the actions for the one that was most recently defined . You specify the actions themselves on the following lines, one action at a time,
and terminate the actions list with a line containing just end.

(gdb) collect data // collect some data

(gdb) while-stepping 5 // single-step 5 times, collect data

(gdb) end              // signals the end of actions.


collect expr1, expr2, ...
Collect values of the given expressions when the tracepoint is hit. This command accepts a comma-separated list of any valid expressions.

In addition to global, static, or local variables, the following special arguments are supported:

$regs
collect all registers
$args
collect all function arguments
$locals
collect all local variables.

Example:

(gdb) trace gdb_c_test
(gdb) actions
Enter actions for tracepoint #1, one per line.
> collect $regs,$locals,$args
> while-stepping 11
  > collect $regs
  > end
> end
(gdb) tstart
[time passes ...]
(gdb) tstop


Using the collected data:

tfind start
Find the first snapshot in the buffer. This is a synonym for tfind 0 (since 0 is the number of the first snapshot).
tfind none
Stop debugging trace snapshots, resume live debugging.
tfind end
Same as `tfind none'.
tfind
No argument means find the next trace snapshot.

The tracepoint facility is currently available only for remote targets.





Reference Link:

ftp://ftp.gnu.org/old-gnu/Manuals/gdb/html_chapter/gdb_10.html

http://stackoverflow.com/questions/3691394/gdb-meaning-of-tstart-error-you-cant-do-that-when-your-target-is-exec

http://stackoverflow.com/questions/38716790/gdb-meaning-of-tstop-error-you-cant-do-that-when-your-target-is-multi-thread

Linux Kernel Tracepoints , TRACE_EVENT() macro and Perf Tool



Why Tracepoints needed:

It is not feasible for the debugger to interrupt the program's execution long enough for the developer to learn anything helpful about its behavior. If the program's correctness depends on its real-time behavior, delays introduced by a debugger might cause the program to change its behavior drastically, or perhaps fail, even when the code itself is correct. It is useful to be able to observe the program's behavior without interrupting it.

What is Trace Points:

A tracepoint placed in code provides a hook to call a function that you can provide at runtime.

A tracepoint can be "on" or "off".

When a tracepoint is "off" it has no effect, except for adding a tiny time penalty and space penalty .

When a tracepoint is "on", the function you provide is called each time the tracepoint is executed, in the execution context of the caller.

When the function provided ends its execution, it returns to the caller.

You can put tracepoints at important locations in the code.

Unlike Ftracer , Trace Point can record local variables of the function.

The tracepoint included a function call in the kernel code that, when enabled, would call a callback function passing the parameters of the tracepoint to that function as if the callback function was called with those parameters.

TRACE_EVENT() macro was specifically made to allow a developer to add tracepoints to their subsystem and have Ftrace automatically be able to trace them.

The anatomy of the TRACE_EVENT() macro:
It must create a tracepoint that can be placed in the kernel code.

It must create a callback function that can be hooked to this tracepoint.

The callback function must be able to record the data passed to it into the tracer ring buffer in the fastest way possible.

It must create a function that can parse the data recorded to the ring buffer and translate it to a human readable format that the tracer can display to a user.


Playing with trace events:

cd /sys/kernel/debug/tracing/events

root@amd-PADEMELON:/sys/kernel/debug/tracing/events/drm# ls
drm_vblank_event  drm_vblank_event_delivered  drm_vblank_event_queued  enable  filter

echo 1 > ./drm/enable

The enable files are used to enable a tracepoint. The enable file in the events directory can enable or disable all events in the system, the enable file in one of the system's directories can enable or disable all events within the system, and the enable file within the specific event  directory can enable or disable that event.


Tracepoint logs can be seen with Ftrace logs :

 3) + 20.320 us   |  dm_crtc_high_irq [amdgpu]();
 0)               |  /* drm_vblank_event_queued: pid=2430, crtc=0, seq=297608 */
 0)               |  send_vblank_event [drm]() {
 0)               |  /* drm_vblank_event_delivered: pid=2430, crtc=0, seq=297608 */
 0)   3.858 us    |  }
 3) + 24.783 us   |  dm_crtc_high_irq [amdgpu]();
 3)               |  dm_pflip_high_irq [amdgpu]() {
 3)               |    drm_send_vblank_event [drm]() {
 3)               |      send_vblank_event [drm]() {
 3)               |        /* drm_vblank_event_delivered: pid=0, crtc=0, seq=297609 */
 3) + 33.556 us   |      }
 3) + 35.227 us   |    }


 We can set requitred events using set_event . It is same as enaabing specific event using enable.

 [tracing] # echo drm_vblank_event drm_vblank_event_delivered drm_vblank_event_queued > set_event


PERF TOOL:
One of the key secrets for quick use of tracepoints is the perf tool . CONFIG_EVENT_PROFILE configuration option should be set.

perf will be available at ./kernel/tools/perf

$ perf list -> List of events available in the system

$ perf stat -a -e kmem:kmalloc sleep 10  -> How many kmalloc() calls are happening on a system

The -a option gives whole-system results

$ perf stat -e kmem:kmalloc make  -> Monitoring allocations during the building of the perf tool




https://www.kernel.org/doc/Documentation/trace/tracepoints.txt - Kernel TracePoint
http://lwn.net/Articles/379903/
http://lwn.net/Articles/381064/
http://lwn.net/Articles/383362/
ftp://ftp.gnu.org/old-gnu/Manuals/gdb/html_chapter/gdb_10.html - GDB Tracepoints usage
https://lwn.net/Articles/346470/  - PERF TOOL