Exploring The GNU GDB Static Tracepoints: A Complete Overview


GNU GDB Static Tracepoints with LTTng

GDB static tracepoints are a valuable feature for developers who need to quickly gather information about a program’s behavior without impacting performance. When integrated with the LTTng user space tracer, these static tracepoints offer even more capabilities for analyzing program behavior. By using GDB static tracepoints, developers can efficiently identify and resolve issues in complex systems, making it an essential tool for debugging and troubleshooting.

GDB Static and Fast Tracepoints

GDB static tracepoints and fast tracepoints are not the same, although they do share some similarities.

Fast tracepoints are a type of tracepoint that is optimized for performance. They are designed to minimize the impact on the target system’s resources by using a simplified expression evaluator and by not recording any data. Fast tracepoints are primarily used to collect performance-related data, such as the number of times a function is called or the time spent in a particular code block.

Static tracepoints, on the other hand, are a type of tracepoint that allows the user to specify a fixed expression to evaluate when the tracepoint is hit. Unlike regular tracepoints, which allow users to specify an arbitrary expression to evaluate, static tracepoints can only execute a fixed expression that is specified at the time the tracepoint is created. Static tracepoints are designed to quickly gather information about the program’s behavior without incurring significant performance overhead.

While both fast and static tracepoints are optimized for performance, they serve different purposes and have different capabilities in GDB.

GDB Static Tracepoints and LTTng

  • What is the connection between GDB static tracepoints and LTTng?

LTTng (Linux Trace Toolkit Next Generation) is a tracing framework for Linux that allows developers to monitor the behavior of the operating system and applications running on it. LTTng provides a number of features for tracing and debugging, including support for kernel and user-space tracing, low-overhead tracing, and live tracing.

One of the features of LTTng is the ability to integrate with GDB’s static tracepoints. LTTng can be used to trace a program’s behavior and record the values of static tracepoints when they are hit. This allows developers to quickly gather information about a program’s behavior without incurring significant performance overhead.

By integrating with LTTng, GDB’s static tracepoints can be used in conjunction with other tracing and debugging tools, allowing developers to get a more complete picture of a program’s behavior. This can be particularly useful in complex systems where multiple components are interacting with each other and tracing is necessary to understand the root cause of a problem.

Why Integrate with LTTng?

Lets now review the advantages of integrating LTTng with GDB static tracepoints.

  1. Low overhead tracing
    • LTTng is designed to provide low-overhead tracing that doesn’t significantly impact the performance of the system being traced.
    • By integrating GDB’s static tracepoints with LTTng, developers can gather detailed information about a program’s behavior without incurring significant performance overhead.
  2. Live tracing
    • LTTng provides support for live tracing, which allows developers to trace a running program and analyze its behavior in real-time.
    • By integrating GDB’s static tracepoints with LTTng, developers can quickly gather information about a program’s behavior as it runs, rather than having to stop the program and manually inspect its state.
  3. Integration with other tracing tools
    • LTTng can be used in conjunction with other tracing and debugging tools, allowing developers to get a more complete picture of a program’s behavior.
    • By integrating GDB’s static tracepoints with LTTng, developers can use them in conjunction with other tracing tools to get a more detailed view of a program’s behavior.

Overall, integrating LTTng with GDB’s static tracepoints can provide developers with a powerful set of tools for tracing and debugging programs, allowing them to quickly identify and fix issues in complex systems.

Userspace Trace (UST) Support

GDB server offers support for static tracepoints on certain targets. Currently, GDB server supports the UST (LTTng Userspace Tracer) tracing engine, which provides developers with a powerful set of tools for tracing and debugging programs. By using GDB server’s static tracepoints and integrating with UST, developers can gather detailed information about a program’s behavior and identify and resolve issues efficiently. With the support of UST, GDB server offers enhanced tracing capabilities for users, making it an essential tool for debugging in complex systems.

For static tracepoints to work, 2 things must happen.

  1. A special library called the in-process agent (IPA), must be loaded in the inferior process.
  2. In-process agent library must be build with static tracepoint support.

1- Add Static Tracepoints Support

GDB userspace tracer(UST) support is automatically available if UST development headers are found in the standard include path when gdbserver is built.

How to explicitly enable GDB userspace tracer?

You can explicitly configure the gdbserver using

--with-ust
How to disable GDB userspace tracer?

You can explicitly disable the support using

--with-ust=no

2- Load The Userspace Trace Agent

There are several ways to load the in-process agent in your program:

You can link your program dynamically with the in-process agent library. On
most systems, this is accomplished by adding -linproctrace to the link command. [1]

Using the system’s preloading mechanisms

You can force loading the in-process agent at startup time by using your system’s support for preloading shared libraries. Many Unixes support the concept of preloading user defined libraries. In most cases, you do that by specifying LD_PRELOAD=libinproctrace.so in the environment.

  • See also the description of gdbserver’s –wrapper command line option.
Using gdb to force loading the agent at run time

On some systems, you can force the inferior to load a shared library, by calling
a dynamic loader function in the inferior that takes care of dynamically looking
up and loading a shared library. On most Unix systems, the function is dlopen.
You’ll use the call command for that.

  • (gdb) call dlopen (“libinproctrace.so”, …)
    • Note that on most Unix systems, for the dlopen function to be available, the program needs to be linked with -ldl
Using The System’s Dynaming Loader

On systems that have a userspace dynamic loader, like most Unix systems, when you
connect to gdbserver using target remote, you’ll find that the program is stopped at
the dynamic loader’s entry point, and no shared library has been loaded in the program’s
address space yet, including the in-process agent. [1]

  • In that case, before being able to use static tracepoints feature, you need to let the loader run and load the shared libraries.

The simplest way to do that is to run the program to the main procedure. E.g.,
if debugging a C or C++ program, start gdbserver like so:

  • $ gdbserver :9999 myprogram

Start GDB and connect to gdbserver like so, and run to main:

  • $ gdb myprogram
  • (gdb) target remote myhost:9999
  • 0x00007f215893ba60 in ?? () from /lib64/ld-linux-x86-64.so.2
  • (gdb) b main
  • (gdb) continue

The in-process tracing agent library should now be loaded into the process; you can
confirm it with the info sharedlibrary command, which will list libinproctrace.so as
loaded in the process.

You are now ready to list static tracepoint markers, probe static tracepoints markers, and start tracing.

References:

[1] GDB Manual, available at gdb.pdf (sourceware.org)


Leave a Reply

Your email address will not be published. Required fields are marked *