source: rtems-docs/user/tracing/tracelinker.rst @ 21c4a44

5
Last change on this file since 21c4a44 was 21c4a44, checked in by Sebastian Huber <sebastian.huber@…>, on 01/30/19 at 10:40:05

user: Add basic event recording documentation

Update #3665.

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