Notice: We have migrated to GitLab launching 2024-05-01 see here: https://gitlab.rtems.org/

Changes between Version 7 and Version 8 of Developer/Tracing/Trace_Linker


Ignore:
Timestamp:
03/16/15 02:05:41 (9 years ago)
Author:
Chris Johns
Comment:

Update.

Legend:

Unmodified
Added
Removed
Modified
  • Developer/Tracing/Trace_Linker

    v7 v8  
    3939The trace linker requires you provide a configuration file using the `-C` or `--config`  option. This is an INI detailed in the Configuration section.
    4040
     41If you are working with new configuration files and you want to view the files the trace linker generates add the `-k` option to keep the temporary files, and `-W` to specify an explicit wrapper C file name.
     42
    4143== Wrapping ==
    4244
     
    4648
    4749The trace linker generates C code with a wrapper for each function to be instrumented. The trace code generated is driven by the configuration INI files.
     50
     51== Function Signatures ==
     52
     53A function signature is the function's declaration. It is the name of the function, the return value and the arguments. Tracing using function wrappers requires we have accurate function signatures and ideally we would like to determine the function signature from the data held in ELF files. ELF files can contain DWARF data, the ELF debugging data format. In time the trace project would like to support `libdwarf` so the DWARF data can be accessed and use to determine a function's signature. This work is planned but not scheduled to be done and so in the meantime we explicitly define the function signatures in the configuration files.
    4854
    4955== Configuration ==
     
    175181A trace section can reference other trace sections of a specific type. This allows a trace sections to build on other trace sections.
    176182
    177 Function signatures are specified with the function being the key's name and they key's value is return value and a list of function arguments.
     183Function signatures are specified with the function being the key's name and the key's value being the return value and a list of function arguments.
    178184
    179185=== Generators ===
    180186
    181 Generators sections specify how to generate trace wrapping code.
     187Generators sections specify how to generate trace wrapping code. The section's name specifies the generator and can be listed in a `generator` key in a `tracer` or `trace` section.
     188
     189A generator specifies the code generated when:
     190
     191* Entering a trace function (`entry-trace`)
     192* Entry argument of a trace function (`arg-trace`), called once per argument
     193* Return value of a trace function (`ret-trace`), called if not `void`.
     194* Exit value of a trace function (`exit-trace`)
     195
     196The the generator is not interested in a specific phase it does not need to define and nothing will be generated. For example code to profile specific function may only provide the `entry-trace` and `exit-trace` code where a nano-second time stamp is taken.
     197
     198The section supports:
     199
     200 headers:: List of header sections.
     201 header:: A header key. Typically the include code.
     202 entry-trace: The code or call made on entry to a function.
     203 arg-trace:: The code or call made for each argument to a function.
     204 ret-trace:: The code or call made with the return value if not `void`.
     205 exit-trace:: The code or call made after the trace function has exited.
     206 code:: Code to be added into the trace file. The code is tagged between `<<<CODE` and `CODE` markers.
     207
     208An example generator section is:
     209
     210{{{
     211#!c
     212[printk-generator]
     213headers = printk-generator-headers
     214entry-trace = "rtld_pg_printk_entry(@FUNC_NAME@, (void*) &@FUNC_LABEL@);"
     215arg-trace = "rtld_pg_printk_arg(@ARG_NUM@, @ARG_TYPE@, @ARG_SIZE@, (void*) &@ARG_LABEL@);"
     216exit-trace = "rtld_pg_printk_exit(@FUNC_NAME@, (void*) &@FUNC_LABEL@);"
     217ret-trace = "rtld_pg_printk_ret(@RET_TYPE@, @RET_SIZE@, (void*) &@RET_LABEL@);"
     218code = <<<CODE
     219static inline void rtld_pg_printk_entry(const char* func_name,
     220                                        void*       func_addr)
     221{
     222  printk (">>> %s (0x%08x)\n", func_name, func_addr);
     223}
     224static inline void rtld_pg_printk_arg(int         arg_num,
     225                                     const char* arg_type,
     226                                     int         arg_size,
     227                                     void*       arg)
     228{
     229  const unsigned char* p = arg;
     230  int   i;
     231  printk (" %2d] %s(%d) = ", arg_num, arg_type, arg_size);
     232  for (i = 0; i < arg_size; ++i, ++p) printk ("%02x", (unsigned int) *p);
     233  printk ("\n");
     234}
     235static inline void rtld_pg_printk_exit(const char* func_name,
     236                                       void*       func_addr)
     237{
     238  printk ("<<< %s (0x%08x)\n", func_name, func_addr);
     239}
     240static inline void rtld_pg_printk_ret(const char* ret_type,
     241                                      int         ret_size,
     242                                      void*       ret)
     243{
     244  const unsigned char* p = ret;
     245  int   i;
     246  printk (" rt] %s(%d) = ", ret_type, ret_size);
     247  for (i = 0; i < ret_size; ++i, ++p) printk ("%02x", (unsigned int) *p);
     248  printk ("\n");
     249}
     250CODE
     251
     252[printk-generator-headers]
     253header = "#include <stdio.h>"
     254}}}
     255
     256The generator code can use a number of token's that are expanded when generating trace functions. They are:
     257
     258 @FUNC_NAME@:: The name of the function being wrapped.
     259 @FUNC_LABEL@:: The C label of the function being wrapped. You can take the address of this label.
     260 @ARG_NUM@:: The argument number bring processed.
     261 @ARG_TYPE@:: The type of the argument.
     262 @ARG_SIZE@::  The size of the argument in bytes.
     263 @ARG_LABEL@:: The C label of the argument. You can take the address of this label.
     264 @RET_TYPE@:: The type of the return value.
     265 @RET_SIZE@:: The size of the return value in bytes.
     266 @RET_LABEL@:: The C label of the return value as held in the wrapping code.
     267
     268== Limitation ==
     269
     270The trace linker and software tracing in this way currently has some limitations. The are:
     271
     272* Function signatures are held in configuration file and so a change in a signature will not be automatically handled.
     273* Variable argument lists cannot be wrapped.
     274* C++ is not supported. In time we would like to add C++ support via the demangler support in the RTEMS Toolkit, however there are C++ constructs that make wrapping difficult such as templates. C++ that results in explicit calls should be able to be wrapped.