source: rtems-docs/user/tracing/tracelinker.rst @ 8f4f80d

5
Last change on this file since 8f4f80d was 8f4f80d, checked in by Vidushi Vashishth <reachvidu@…>, on 06/14/18 at 14:17:58

Adding Trace Documentation

  • Updates #3454
  • This commit adds Tracing Framework Chapter in the RTEMS User Manual
  • It comprises of subchapters on RTEMS Trace Linker, Capture Engine, Trace generation techniques explaining trace generation using Trace Buffering and Printk generators and sample demonstrations.
  • Property mode set to 100644
File size: 19.1 KB
Line 
1.. comment SPDX-License-Identifier: CC-BY-SA-4.0
2
3.. comment: Copyright (c) 2016 Chris Johns <chrisj@rtems.org>
4.. comment: All rights reserved.
5
6.. _tracelinker:
7
8Trace Linker
9************
10
11RTEMS trace linker is a post link tool central to the RTEMS trace framework. It
12is installed as a part of the RTEMS Tool Project. The RTEMS Trace Linker is a
13post link tool that performs a re-link of your application to produce a trace
14executable. A trace executable has been instrumented by the RTEMS Trace Linker
15with additional code that implements software tracing. A key requirement of the
16trace process in RTEMS is to take existing code in a compiled format (ELF) and
17instrument it without rebuilding that code from source and without annotating
18that source with trace code.
19
20Command Line
21============
22
23A typical command to invoke the trace linker consists of two parts separated by
24``--``.  The first part controls the trace linker and provides the various
25options it needs and the second part is a standard linker command line you would
26use to link an RTEMS application. The current command line for trace linker
27consists of:
28
29.. code-block:: shell
30
31  $ rtems-tld -h
32  rtems-trace-ld [options] objects
33  Options and arguments:
34   -h          : help (also --help)
35   -V          : print linker version number and exit (also --version)
36   -v          : verbose (trace import parts), can supply multiple times
37                 to increase verbosity (also --verbose)
38   -w          : generate warnings (also --warn)
39   -k          : keep temporary files (also --keep)
40   -c compiler : target compiler is not standard (also --compiler)
41   -l linker   : target linker is not standard (also --linker)
42   -E prefix   : the RTEMS tool prefix (also --exec-prefix)
43   -f cflags   : C compiler flags (also --cflags)
44   -r path     : RTEMS path (also --rtems)
45   -B bsp      : RTEMS arch/bsp (also --rtems-bsp)
46   -W wrapper  : wrapper file name without ext (also --wrapper)
47   -C ini      : user configuration INI file (also --config)
48   -P path     : user configuration INI file search path (also --path)
49
50The trace linker generates code that needs to be compiled and linked to the
51application executable so it needs to know the target compiler and `CFLAGS`.
52There are a couple of ways to do this. The simplest is to provide the path to
53RTEMS using the `-r` option and the architecture and BSP name in the standard
54RTEMS format of arch/bsp. The trace linker will extract the compiler and flags
55used to build RTEMS and will use them. If you require specific options you can
56use the `-f`, `-c`, `-l`, and `-E` options to provide them. If the functions you
57are tracing use types from your code then add the include path to the `CFLAGS`.
58
59The trace linker requires you to provide a user configuration file using the
60`-C` or ``--config`` option. This is an INI format file detailed in the
61Configuration section. You can also provide an INI file search path using the
62`-P` option.
63
64If you are working with new configuration files and you want to view the files
65the trace linker generates, add the `-k` option to keep the temporary files, and
66`-W` to specify an explicit wrapper C file name. If you set the
67``dump-on-error`` option in the configuration options section you will get a
68dump of the configuration on an error.
69
70Configuration (INI) files
71=========================
72
73The Trace Linker is controlled using configuration files. Configuration files
74are categorized into 3 types:
75
76- User Configuration: These are specific to the user application to be traced.
77  This file initializes the values of the trace generator, triggers, enables,
78  and traces.
79
80- Tracer Configuration: These are like a library of common or base trace
81  functions that can be referenced by an application. These files tend to hold
82  the details needed to wrap a specific set of functions. Examples provided with
83  the RTEMS Linker are the RTEMS API and Libc.
84
85- Generator Configuration: This is used to encapsulate a specific method of
86  tracing. RTEMS currently provides generators for trace buffering, printk, and
87  printf.
88
89The configuration files are in the *INI file format* which is composed of
90`sections`. Each section has a section name and set of *keys* which consist of
91*names* and *values*. A typical key is of the form ``name=value``. Keys can be
92used to include other INI files using the include key name. This is shown in the
93following example where the values indicate rtems and rtld-base configuration
94files:
95
96.. code-block:: shell
97
98  include = rtems.ini, rtld-base.ini
99
100The trace linker also uses values in keys to specify other sections. In this
101example the functions name lists `test-trace-funcs` and that section contains a
102headers key that further references a section called `test-headers`:
103
104.. code-block:: shell
105
106  functions = test-trace-funcs, rtems-api
107
108  [test-trace-funcs]
109  ; Parsed via the 'function-set', not parse as a 'trace'.
110  headers = test-headers
111
112  [test-headers]
113  header = '#include "test-trace-1.h"'
114
115The format of a configuration file is explained next. Snippets of the file:
116`test-trace.ini` have been used for explicit understanding. This file can
117be found in the rtems-tools directory of the rtems installation.
118
119Tracer Section
120--------------
121
122The topmost level section is the ``tracer`` section. It can contains the
123following keys:
124
125- ``name``: The name of trace being linked.
126
127- ``options``: A list of option sections.
128
129- ``defines``: A list of sections containing defines or define record.
130
131- ``define``: A list of define string that are single or double quoted.
132
133- ``enables``: The list of sections containing enabled functions to trace.
134
135- ``triggers``: The list of sections containing enabled functions to trigger
136  trace on.
137
138- ``traces``: The list of sections containing function lists to trace.
139
140- ``functions``: The list of sections containing function details.
141
142- ``include``: The list of files to include.
143
144The tracer section of the file:`test-trace.ini` is shown below with explanatory
145comments.
146
147.. code-block:: shell
148
149  ;
150  ; RTEMS Trace Linker Test Configuration.
151  ;
152  ; We must provide a top level trace section.
153  ;
154  [tracer]
155  ;
156  ; Name of the trace.
157  ;
158  name = RTEMS Trace Linker Test
159  ;
160  ; The BSP.
161  ;
162  bsp = sparc/sis
163  ;
164  ; Functions to trace.
165  ;
166  traces = test-trace, test-trace-funcs, rtems-api-task
167  ;
168  ; Specify the options.
169  ;
170  options = test-options
171  ;
172  ; Define the function sets. These are the function's that can be
173  ; added to the trace lists.
174  ;
175  functions = test-trace-funcs, rtems-api
176  ;
177  ; Include RTEMS Trace support.
178  ;
179  include = rtems.ini, rtld-base.ini
180
181Options section
182---------------
183
184The options section in the fileio-trace.ini is called the `fileio-options`. A
185general options section can contain following sets of keys:
186
187- ``dump-on-error``: Dump the parsed configuration data on error. The value can
188  be true or false.
189
190- ``verbose``: Set the verbose level. The value can be true or a number value.
191
192- ``prefix``: The prefix for the tools and an install RTEMS if rtems-path is not
193  set.
194
195- ``cc``: The compiler used to compile the generated wrapper code. Overrides the
196  BSP configuration value if a BSP is specified.
197
198- ``ld``: The linker used to link the application. The default is the cc value
199  as read from the BSP configuration if specified. If your application contains
200  C++ code use this setting to the change the linker to g++.
201
202- ``cflags``: Set the CFLAGS used to compiler the wrapper. These flags are
203  pre-pended to the BSP read flags if a BSP is specified. This option is used
204  to provide extra include paths to header files in your application that
205  contain types referenced by functions being traced.
206
207- ``rtems-path``: The path to an install RTEMS if not installed under the
208  prefix.
209
210- ``rtems-bsp``: The BSP we are building the trace executable for. The is an
211  arch and bsp pair. For example sparc/erc32.
212
213The options section of the file: `test-trace.ini` uses two of the aforementioned
214keys as shown below:
215
216.. code-block:: shell
217
218  ;
219  ; Options can be defined here or on the command line.
220  ;
221  [test-options]
222  prefix = /development/rtems/5
223  verbose = true
224
225Trace Section
226-------------
227
228A trace section defines how trace wrapper functions are built. To build a trace
229function that wraps an existing function in an ELF object file or library
230archive we need to have the function's signature. A signature is the function's
231declaration with any types used. The signature has specific types and we need
232access to those types which means the wrapper code needs to include header files
233that define those types. There may also be specific defines needed to access
234those types. A trace section can contain the following keys:
235
236- ``generator``: The generator defines the type of tracing being used.
237
238- ``headers``: List of sections that contain header file's keys.
239
240- ``header``: A header key. Typically the include code.
241
242- ``defines``: List of sections that contain defines.
243
244- ``define``: A define key. Typically the define code.
245
246- ``signatures``: List of function signature sections.
247
248- ``trace``: Functions that are instrumented with trace code.
249
250The trace section of the file: `test-trace.ini` is shown below. A trace section
251can reference other trace sections of a specific type. This allows a trace
252sections to build on other trace sections.
253
254.. code:: shell
255
256  ; User application trace example.
257  ;
258  [test-trace]
259  generator = printf-generator
260  ; Just here for testing.
261  trace = test_trace_3
262
263  [test-trace-funcs]
264  ; Parsed via the 'function-set', not parse as a 'trace'.
265  headers = test-headers
266  header = '#include "test-trace-2.h"'
267  defines = test-defines
268  define = "#define TEST_TRACE_2 2"
269  signatures = test-signatures
270  ; Parsed via the 'trace', not parsed as a function-set
271  trace = test_trace_1, test_trace_2
272
273  [test-headers]
274  header = '#include "test-trace-1.h"'
275
276  [test-defines]
277  define = "#define TEST_TRACE_1 1"
278
279  [test-signatures]
280  test_trace_1 = void, int
281  test_trace_2 = test_type_2, test_type_1
282  test_trace_3 = float, float*
283
284Function Section
285----------------
286
287Function sections define functions that can be traced. Defining a function so it
288can be traced does not mean it is traced. The function must be added to a trace
289list to be traced. Function sections provide any required defines, header files,
290and the function signatures.
291
292A function signature is the function's declaration. It is the name of the
293function, the return value, and the arguments. Tracing using function wrappers
294requires that we have accurate function signatures and ideally we would like to
295determine the function signature from the data held in ELF files. ELF files can
296contain DWARF data, the ELF debugging data format. In time the trace project
297would like to support libdwarf so the DWARF data can be accessed and used to
298determine a function's signature. This work is planned but not scheduled to be
299done and so in the meantime we explicitly define the function signatures in the
300configuration files.
301
302A function section can consist of the following keys:
303
304- ``headers``: A list of sections containing headers or header records.
305- ``header``: A list of include string that are single or double quoted.
306- ``defines``: A list of sections containing defines or define record.
307- ``defines``: A list of define string that are single or double quoted.
308- ``signatures``: A list of section names of function signatures.
309- ``includes``: A list of files to include.
310
311Function signatures are specified with the function name being the key's name
312and the key's value being the return value and a list of function arguments. You
313need to provide void if the function uses void. Variable argument list are
314currently not supported. There is no way to determine statically a variable
315argument list. The function section in the file: `test-trace.ini` has been
316labeled as `test-trace-funcs`. This can be seen in the file snippet of the
317previous section.
318
319Generators
320----------
321
322The trace linker's major role is to wrap functions in the existing executable
323with trace code. The directions on how to wrap application functions is provided
324by the generator configuration. The wrapping function uses a GNU linker option
325called --wrap=symbol. The GNU Ld manual states:
326
327"Use a wrapper function for symbol. Any undefined reference to symbol will be
328resolved to __wrap_symbol. Any undefined reference to __real_symbol will be
329resolved to symbol."
330
331Generator sections specify how to generate trace wrapping code. The trace
332linker and generator section must match to work. The trace linker expects a some
333things to be present when wrapping functions. The section's name specifies the
334generator and can be listed in a generator key in a tracer or trace section. If
335the generator is not interested in a specific phase it does not need to define
336it. Nothing will be generated in regard to this phase. For example code to
337profile specific functions may only provide the entry-trace and exit-trace code
338where a nano-second time stamp is taken.
339
340The generate code will create an entry and exit call and the generator code
341block can be used to allocate buffer space for each with the lock held. The
342entry call and argument copy is performed with the lock released. The buffer
343space having been allocated will cause the trace events to be in order. The same
344goes for the exit call. Space is allocated in separate buffer allocate calls so
345the blocking calls will have the exit event appear in the correct location in
346the buffer.
347
348The following keys can be a part of the generator configuration:
349
350- ``headers``: A list of sections containing headers or header records.
351- ``header``: A list of include string that are single or double quoted.
352- ``defines``: A list of sections containing defines or define record.
353- ``define``: A list of define string that are single or double quoted.
354- ``entry-trace``: The wrapper call made on a function's entry. Returns bool
355  where true is the function is being traced. This call is made without the lock
356  being held if a lock is defined.
357- ``arg-trace``: The wrapper call made for each argument to the trace function
358  if the function is being traced. This call is made without the lock being held
359  if a lock is defined.
360- ``exit-trace``: The wrapper call made after a function's exit. Returns bool
361  where true is the function is being traced. This call is made without the lock
362  being held if a lock is defined.
363- ``ret-trace``: The wrapper call made to log the return value if the function
364  is being traced. This call is made without the lock being held if a lock is
365  defined.
366- ``lock-local``: The wrapper code to declare a local lock variable.
367- ``lock-acquire``: The wrapper code to acquire the lock.
368- ``lock-release``: The wrapper code to release the lock.
369- ``buffer-local``: The wrapper code to declare a buffer index local variable.
370- ``buffer-alloc``: The wrapper call made with a lock held if defined to
371  allocate buffer space to hold the trace data. A suitable 32bit buffer index is
372  returned. If there is no space an invalid index is returned. The generator
373  must handle any overhead space needed. The generator needs to make sure the
374  space is available before making the alloc all.
375- ``code-blocks``: A list of code block section names.
376- ``code``: A code block in <<CODE --- CODE (without the single quote).
377- ``includes``: A list of files to include.
378
379The following macros can be used in wrapper calls:
380
381- ``@FUNC_NAME@``: The trace function name as a quote C string.
382- ``@FUNC_INDEX@``: The trace function index as a held in the sorted list of
383  trace functions by the trace linker. It can be used to index the names,
384  enables, and triggers data.
385- ``@FUNC_LABEL@``: The trace function name as a C label that can be referenced.
386  You can take the address of the label.
387- ``@FUNC_DATA_SIZE@``: The size of the data in bytes.
388- ``@FUNC_DATA_ENTRY_SIZE@``: The size of the entry data in bytes.
389- ``@FUNC_DATA_RET_SIZE@``: The size of the return data in bytes.
390- ``@ARG_NUM@``: The argument number to the trace function.
391- ``@ARG_TYPE@``: The type of the argument as a C string.
392- ``@ARG_SIZE@``: The size of the type of the argument in bytes.
393- ``@ARG_LABEL@``: The argument as a C label that can be referenced.
394- ``@RET_TYPE@``: The type of the return value as a C string.
395- ``@RET_SIZE@``: The size of the type of the return value in bytes.
396- ``@RET_LABEL@``: The return value as a C label that can be referenced.
397
398The `buffer-alloc`, `entry-trace`, and `exit-trace` can be transformed using the
399following macros:
400
401- ``@FUNC_NAME@``
402- ``@FUNC_INDEX@``
403- ``@FUNC_LABEL@``
404- ``@FUNC_DATA_SZIE@``
405- ``@FUNC_DATA_ENTRY_SZIE@``
406- ``@FUNC_DATA_EXIT_SZIE@``
407
408The `arg-trace` can be transformed using the following macros:
409
410- ``@ARG_NUM@``
411- ``@ARG_TYPE@``
412- ``@ARG_SIZE@``
413- ``@ARG_LABEL@``
414
415The `ret-trace` can be transformed using the following macros:
416
417- ``@RET_TYPE@``
418- ``@RET_SIZE@``
419- ``@RET_LABEL@``
420
421The file: `test-trace.ini` specifies ``printf-generator`` as its generator. This
422section can be found in the file: `rtld-print.ini` in the rtems-tools directory
423and is shown below:
424
425.. code:: shell
426
427  ;
428  ; A printf generator prints to stdout the trace functions.
429  ;
430  [printf-generator]
431  headers = printf-generator-headers
432  entry-trace = "rtld_pg_printf_entry(@FUNC_NAME@, (void*) &@FUNC_LABEL@);"
433  arg-trace = "rtld_pg_printf_arg(@ARG_NUM@, @ARG_TYPE@, @ARG_SIZE@, (void*) &@ARG_LABEL@);"
434  exit-trace = "rtld_pg_printf_exit(@FUNC_NAME@, (void*) &@FUNC_LABEL@);"
435  ret-trace = "rtld_pg_printf_ret(@RET_TYPE@, @RET_SIZE@, (void*) &@RET_LABEL@);"
436  code = <<<CODE
437  static inline void rtld_pg_printf_entry(const char* func_name,
438                                          void*       func_addr)
439  {
440    printf (">>> %s (0x%08x)\n", func_name, func_addr);
441  }
442  static inline void rtld_pg_printf_arg(int         arg_num,
443                                        const char* arg_type,
444                                        int         arg_size,
445                                        void*       arg)
446  {
447    const unsigned char* p = arg;
448    int   i;
449    printf (" %2d] %s(%d) = ", arg_num, arg_type, arg_size);
450    for (i = 0; i < arg_size; ++i, ++p) printf ("%02x", (unsigned int) *p);
451    printf ("\n");
452  }
453  static inline void rtld_pg_printf_exit(const char* func_name,
454                                         void*       func_addr)
455  {
456    printf ("<<< %s (0x%08x)\n", func_name, func_addr);
457  }
458  static inline void rtld_pg_printf_ret(const char* ret_type,
459                                        int         ret_size,
460                                        void*       ret)
461  {
462    const unsigned char* p = ret;
463    int   i;
464    printf (" rt] %s(%d) = ", ret_type, ret_size);
465    for (i = 0; i < ret_size; ++i, ++p) printf ("%02x", (unsigned int) *p);
466    printf ("\n");
467  }
468  CODE
469
470  [printf-generator-headers]
471  header = "#include <stdio.h>"
472
473The trace linker generates C code with a wrapper for each function to be
474instrumented. The trace code generated is driven by the configuration INI files.
475
476Development
477===========
478
479The Trace Linker is part of the RTEMS tools git repository available at :
480https://git.rtems.org/rtems-tools
481The RTEMS tools project utilizes the waf build system. Use the following
482commands in the topmost build directory to build the tools project:
483
484First we configure using:
485
486.. code-block:: shell
487
488  $./waf configure --prefix=$HOME/development/rtems/5
489
490Then we build and install using:
491
492.. code-block:: shell
493
494  $./waf build install
Note: See TracBrowser for help on using the repository browser.