From: Antoine Busque Date: Thu, 19 May 2016 16:21:29 +0000 (-0400) Subject: Standardise spelling of debug info X-Git-Tag: v1.4.0~12 X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=eb75a494900f763d9daca6a9bab5a8f01ffe552f Standardise spelling of debug info Debug info being short for debugging information is two separate words. Therefore, the debuginfo spelling is erroneous. Variables and defines throughout the code and build system should therefore use 'debug_info' or 'DEBUG_INFO', whereas command-line options and file names should use the 'debug-info' form. In free form text (i.e. comments and documentation), 'debug info' should be used, or the long form 'debugging information'. Signed-off-by: Antoine Busque Signed-off-by: Jérémie Galarneau --- diff --git a/configure.ac b/configure.ac index f4dc1172..a08ec113 100644 --- a/configure.ac +++ b/configure.ac @@ -128,11 +128,11 @@ AC_CHECK_FUNCS([ \ ]) MINGW32=no -DEFAULT_ENABLE_DEBUGINFO=yes +DEFAULT_ENABLE_DEBUG_INFO=yes AS_CASE([$host_os], [solaris*|darwin*], [ - DEFAULT_ENABLE_DEBUGINFO=no + DEFAULT_ENABLE_DEBUG_INFO=no ], [mingw*], [ @@ -250,24 +250,26 @@ else fi -# Set default enable state for debug info -AS_IF([test "x$DEFAULT_ENABLE_DEBUGINFO" = xyes], [enable_debuginfo=yes], [enable_debuginfo=no]) +# Set default enable state for debug info. +# The _enable_debug_info variable is prepended with an underscore to +# avoid clashing with the one generated by AC_ARG_ENABLE. +AS_IF([test "x$DEFAULT_ENABLE_DEBUG_INFO" = xyes], [_enable_debug_info=yes], [_enable_debug_info=no]) -# Optional debuginfo feature +# Optional debug info feature # Do _not_ indent the help string below (appears in the configure --help # output). AC_ARG_ENABLE([debug-info], -[AC_HELP_STRING([--enable-debug-info], [enable the debug-info feature (default on Linux)])] -[AC_HELP_STRING([--disable-debug-info], [disable the debug-info feature (default on OS X and Solaris)])], - [AS_IF([test "x$enableval" = xyes], [enable_debuginfo=yes], [enable_debuginfo=no])], []) +[AC_HELP_STRING([--enable-debug-info], [enable the debug info feature (default on Linux)])] +[AC_HELP_STRING([--disable-debug-info], [disable the debug info feature (default on OS X and Solaris)])], + [AS_IF([test "x$enableval" = xyes], [_enable_debug_info=yes], [_enable_debug_info=no])], []) -AM_CONDITIONAL([ENABLE_DEBUGINFO], [test "x$enable_debuginfo" = xyes]) -AS_IF([test "x$enable_debuginfo" = xyes], [ +AM_CONDITIONAL([ENABLE_DEBUG_INFO], [test "x$_enable_debug_info" = xyes]) +AS_IF([test "x$_enable_debug_info" = xyes], [ # Check if libelf and libdw are present - AC_CHECK_LIB([elf], [elf_version], [], [AC_MSG_ERROR(Missing libelf (from elfutils >= 0.154) which is required by debug-info. You can disable this feature using --disable-debug-info.)]) - AC_CHECK_LIB([dw], [dwarf_begin], [], [AC_MSG_ERROR(Missing libdw (from elfutils >= 0.154) which is required by debug-info. You can disable this feature using --disable-debug-info.)]) - AX_LIB_ELFUTILS([0], [154], [], [AC_MSG_ERROR(elfutils >= 0.154 is required to use the debug-info feature. You can disable this feature using --disable-debug-info.)]) - AC_DEFINE([ENABLE_DEBUGINFO], [1], [Define to 1 if you enable the 'debug-info' feature]) + AC_CHECK_LIB([elf], [elf_version], [], [AC_MSG_ERROR(Missing libelf (from elfutils >= 0.154) which is required by debug info. You can disable this feature using --disable-debug-info.)]) + AC_CHECK_LIB([dw], [dwarf_begin], [], [AC_MSG_ERROR(Missing libdw (from elfutils >= 0.154) which is required by debug info. You can disable this feature using --disable-debug-info.)]) + AX_LIB_ELFUTILS([0], [154], [], [AC_MSG_ERROR(elfutils >= 0.154 is required to use the debug info feature. You can disable this feature using --disable-debug-info.)]) + AC_DEFINE([ENABLE_DEBUG_INFO], [1], [Define to 1 if you enable the 'debug info' feature]) ], []) PKG_CHECK_MODULES(GMODULE, [gmodule-2.0 >= 2.0.0]) @@ -372,8 +374,8 @@ PPRINT_PROP_BOOL([Python bindings], $value) test "x$enable_python_bindings_doc" = "xyes" && value=1 || value=0 PPRINT_PROP_BOOL([Python bindings doc], $value) -# debug-info enabled/disabled -test "x$enable_debuginfo" = "xyes" && value=1 || value=0 +# debug info enabled/disabled +test "x$_enable_debug_info" = "xyes" && value=1 || value=0 PPRINT_PROP_BOOL([Debug information output], $value) diff --git a/converter/Makefile.am b/converter/Makefile.am index aba3333d..47693f5a 100644 --- a/converter/Makefile.am +++ b/converter/Makefile.am @@ -19,8 +19,8 @@ babeltrace_LDADD = \ $(top_builddir)/formats/bt-dummy/libbabeltrace-dummy.la \ $(top_builddir)/formats/lttng-live/libbabeltrace-lttng-live.la -if ENABLE_DEBUGINFO -babeltrace_LDADD += $(top_builddir)/lib/libdebuginfo.la +if ENABLE_DEBUG_INFO +babeltrace_LDADD += $(top_builddir)/lib/libdebug-info.la endif babeltrace_log_SOURCES = babeltrace-log.c diff --git a/converter/babeltrace.c b/converter/babeltrace.c index d80b1198..2e4003ca 100644 --- a/converter/babeltrace.c +++ b/converter/babeltrace.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include @@ -138,7 +138,7 @@ static struct poptOption long_options[] = { { "clock-gmt", 0, POPT_ARG_NONE, NULL, OPT_CLOCK_GMT, NULL, NULL }, { "clock-force-correlate", 0, POPT_ARG_NONE, NULL, OPT_CLOCK_FORCE_CORRELATE, NULL, NULL }, { "stream-intersection", 0, POPT_ARG_NONE, NULL, OPT_STREAM_INTERSECTION, NULL, NULL }, -#ifdef ENABLE_DEBUGINFO +#ifdef ENABLE_DEBUG_INFO { "debug-info-dir", 0, POPT_ARG_STRING, NULL, OPT_DEBUG_INFO_DIR, NULL, NULL }, { "debug-info-full-path", 0, POPT_ARG_NONE, NULL, OPT_DEBUG_INFO_FULL_PATH, NULL, NULL }, { "debug-info-target-prefix", 0, POPT_ARG_STRING, NULL, OPT_DEBUG_INFO_TARGET_PREFIX, NULL, NULL }, @@ -189,7 +189,7 @@ static void usage(FILE *fp) fprintf(fp, " --clock-force-correlate Assume that clocks are inherently correlated\n"); fprintf(fp, " across traces.\n"); fprintf(fp, " --stream-intersection Only print events when all streams are active.\n"); -#ifdef ENABLE_DEBUGINFO +#ifdef ENABLE_DEBUG_INFO fprintf(fp, " --debug-info-dir Directory in which to look for debugging information\n"); fprintf(fp, " files. (default: /usr/lib/debug/)\n"); fprintf(fp, " --debug-info-target-prefix Directory to use as a prefix for executable lookup\n"); diff --git a/doc/debug-info.txt b/doc/debug-info.txt new file mode 100644 index 00000000..98ab1f68 --- /dev/null +++ b/doc/debug-info.txt @@ -0,0 +1,189 @@ +Babeltrace Debug Info Analysis +----------------------------- + +The babeltrace debug info analysis is a set of features which allow +mapping events from a trace to their location in source code or within +a binary file, based on their `ip` (instruction pointer) field. + +Prerequisites +------------- + +In order to install a version of babeltrace with debug info support, +the following libraries are required: + + * libelf + * libdw + +Both of them are provided by the elfutils project +(https://fedorahosted.org/elfutils/), and can be installed through the +elfutils package on Ubuntu, Debian, RHEL, and others. + +Compiling for Debug Info Analysis +--------------------------------- + +Traced programs on which debug info analysis is to be performed can be +compiled in a few different ways, and still lead to useful results. + +Ideally, one should compile the program in debug mode, which is +achieved on gcc by simply using the `-g` flag. This generates debug +information in the operating system's native format, which is then +used by babeltrace to map an event's source location to a file and +line number, and the name of the surrounding function. + +Do note that only debug information in DWARF format, version 2 or +later, is currently supported by babeltrace. Use the `-gdwarf` or +`-gdwarf-(VERSION)` to explicitly generate DWARF debug information. + +If the executable is not compiled with `-g` or an equivalent option +enabled, and thus no DWARF information is available, babeltrace will +use ELF symbols from the executable. Instead of providing source file, +line number and function name, however, the analysis will provide the +name of the nearest function symbol, plus an offset in bytes to the +location in the executable from which the event originated. + +If the executable has neither ELF symbols nor DWARF information, +babeltrace will be unable to map an event to its source location and +will simply display the instruction pointer (address), as in prior +versions of babeltrace. + +Getting the Right Tracer +------------------------ + +Debug info analysis is performed automatically by babeltrace, provided +the trace contains sufficient information. In order to be able to +trace all the necessary information, the following software is +required: + + * lttng-ust version 2.8.0 or later + * lttng-tools, corresponding version + +You can get these from source at: + + * https://github.com/lttng/lttng-ust + * https://github.com/lttng/lttng-tools + +Ubuntu users also have the option of installing via the LTTng daily +PPA: + + * https://launchpad.net/~lttng/+archive/ubuntu/daily + +Tracing for Debug Info Analysis +------------------------------- + +Babeltrace needs some extra information from contexts, namely ip and +vpid, to perform its analysis. These can be enabled after the creation +of a tracing session as follows: + + $ lttng add-context --userspace --type ip --type vpid + +The tracing can then be performed as it normally would. Once the trace +is collected, it can the be read by babeltrace for analysis. + +Analysing the Trace +------------------- + +To perform the analysis, the trace can simply be read as it normally +would: + + $ babeltrace + +Debug info analysis is on by default and will automatically print the +extra source location information if it can find it. A sample output +may look like this: + + [...] + [16:18:15.845829429] (+0.000011697) colossus my_provider:my_first_tracepoint: { cpu_id = 2 }, { ip = 0x7F4D2A5D550E, debug_info = { bin = "libhello.so+0x150e", func = "foo+0xa9", src = "libhello.c:7" }, vpid = 28719 }, { my_string_field = "hello, tracer", my_integer_field = 42 } + [16:18:15.845841484] (+0.000012055) colossus my_provider:my_first_tracepoint: { cpu_id = 2 }, { ip = 0x7F4D2A5D55E0, debug_info = { bin = "libhello.so+0x15e0", func = "bar+0xa9", src = "libhello.c:13" }, vpid = 28719 }, { my_string_field = "recoltes et semailles", my_integer_field = 57 } + [16:18:15.845844852] (+0.000003368) colossus my_provider:my_other_tracepoint: { cpu_id = 2 }, { ip = 0x7F4D2A5D56A5, debug_info = { bin = "libhello.so+0x16a5", func = "baz+0x9c", src = "libhello.c:20" }, vpid = 28719 }, { some_field = 1729 } + [...] + +The interesting part is the debug_info section of the context: + + debug_info = { bin = "libhello.so+0x150e", func = "foo+0xa9", src = "libhello.c:7" } + +This is the expected output for events generated by an executable for +which DWARF information is available. It shows the name of the binary +and offset to the tracepoint, the name of the function containing the +tracepoint instance which generated the event ("foo") and the offset +within the function, and its source location ("libhello.c", line 7). + +The second event in the sample output is of the same type +("my_first_tracepoint"), but it was generated by a different +tracepoint instance, hence the different source location (line 13) and +function ("bar"). + +The third event, of a different type, also shows debug information. + +If DWARF info is absent, but ELF symbols are not stripped, the output +will instead look like this: + + [...] + [16:18:15.845829429] (+0.000011697) colossus my_provider:my_first_tracepoint: { cpu_id = 2 }, { ip = 0x7F4D2A5D550E, debug_info = { bin = "libhello.so+0x150e", func = "foo+0xa9" }, vpid = 28719 }, { my_string_field = "hello, tracer", my_integer_field = 42 } + [16:18:15.845841484] (+0.000012055) colossus my_provider:my_first_tracepoint: { cpu_id = 2 }, { ip = 0x7F4D2A5D55E0, debug_info = { bin = "libhello.so+0x15e0", func = "bar+0xa9" }, vpid = 28719 }, { my_string_field = "recoltes et semailles", my_integer_field = 57 } + [16:18:15.845844852] (+0.000003368) colossus my_provider:my_other_tracepoint: { cpu_id = 2 }, { ip = 0x7F4D2A5D56A5, debug_info = { bin = "libhello.so+0x16a5", func = "baz+0x9c" }, vpid = 28719 }, { some_field = 1729 } + [...] + +The debug information now provides both binary and function location +information, but no source location information, as this requires +DWARF. The function names are in fact resolved using ELF symbols, so +there may be a discrepancy with those provided by DWARF (e.g. in the +case of mangling). + +Paths to the binary and to the source location (if any) can be +expanded by using the command-line option +--debug-info-full-path. Otherwise, only the filename is shown. + +Debug Info and Dynamic Loading +------------------------------ + +Babeltrace can resolve addresses of events originating from +dynamically loaded libraries, provided that some extra information is +collected at tracing time. + +This can be achieved by preloading LTTng UST's libdl helper when +launching the program to be traced, like so: + + $ LD_PRELOAD="liblttng-ust-dl.so" + +The tracing and analysis can now be performed as described in prior +sections, and events from tracepoints in dlopened libraries will be +resolved automatically by babeltrace. + +Separate Debug Info +------------------- + +It is possible to store DWARF debug information separate from an +executable, whether for concerns of file size, or simply to facilitate +the sharing of the debug information. + +This is usually achieved via one of two mechanisms, namely build ID +and debug link. Both methods permit separate executables and debug +information. Their use and operation is described in GDB's +documentation at: + + https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html + +Babeltrace will find separate debug files automatically, provided they +follow the requirements described in the documentation above. The +debug information lookup order is the same as GDB's, that is first +debug info is looked for within the executable, then through the build +ID method in the standard /usr/lib/debug/.build-id/ location, and +finally in the various possible debug link locations. The first debug +information file found is used. + +The --debug-info-dir command-line option can be used to override the +default /usr/lib/debug/ directory used in build ID and debug link +lookups. Multiple debug info directories are currently not supported. + +Target Prefix +------------- + +The debug info analysis uses the paths to the executables as collected +during tracing as one mechanism to resolve DWARF or ELF +information. If the trace was taken on a separate machine, for +instance, it is possible to use --debug-info-target-prefix to specify +a prefix directory, representing the root of the target filesystem, +which will then be used for lookups. For example, if an executable was +located at /usr/bin/foo on the target system, it could be placed at +/home/efficios/target/usr/bin/foo on the system on which the analysis +is performed. In this case, the prefix is /home/efficios/target/. diff --git a/doc/debuginfo.txt b/doc/debuginfo.txt deleted file mode 100644 index 98ab1f68..00000000 --- a/doc/debuginfo.txt +++ /dev/null @@ -1,189 +0,0 @@ -Babeltrace Debug Info Analysis ------------------------------ - -The babeltrace debug info analysis is a set of features which allow -mapping events from a trace to their location in source code or within -a binary file, based on their `ip` (instruction pointer) field. - -Prerequisites -------------- - -In order to install a version of babeltrace with debug info support, -the following libraries are required: - - * libelf - * libdw - -Both of them are provided by the elfutils project -(https://fedorahosted.org/elfutils/), and can be installed through the -elfutils package on Ubuntu, Debian, RHEL, and others. - -Compiling for Debug Info Analysis ---------------------------------- - -Traced programs on which debug info analysis is to be performed can be -compiled in a few different ways, and still lead to useful results. - -Ideally, one should compile the program in debug mode, which is -achieved on gcc by simply using the `-g` flag. This generates debug -information in the operating system's native format, which is then -used by babeltrace to map an event's source location to a file and -line number, and the name of the surrounding function. - -Do note that only debug information in DWARF format, version 2 or -later, is currently supported by babeltrace. Use the `-gdwarf` or -`-gdwarf-(VERSION)` to explicitly generate DWARF debug information. - -If the executable is not compiled with `-g` or an equivalent option -enabled, and thus no DWARF information is available, babeltrace will -use ELF symbols from the executable. Instead of providing source file, -line number and function name, however, the analysis will provide the -name of the nearest function symbol, plus an offset in bytes to the -location in the executable from which the event originated. - -If the executable has neither ELF symbols nor DWARF information, -babeltrace will be unable to map an event to its source location and -will simply display the instruction pointer (address), as in prior -versions of babeltrace. - -Getting the Right Tracer ------------------------- - -Debug info analysis is performed automatically by babeltrace, provided -the trace contains sufficient information. In order to be able to -trace all the necessary information, the following software is -required: - - * lttng-ust version 2.8.0 or later - * lttng-tools, corresponding version - -You can get these from source at: - - * https://github.com/lttng/lttng-ust - * https://github.com/lttng/lttng-tools - -Ubuntu users also have the option of installing via the LTTng daily -PPA: - - * https://launchpad.net/~lttng/+archive/ubuntu/daily - -Tracing for Debug Info Analysis -------------------------------- - -Babeltrace needs some extra information from contexts, namely ip and -vpid, to perform its analysis. These can be enabled after the creation -of a tracing session as follows: - - $ lttng add-context --userspace --type ip --type vpid - -The tracing can then be performed as it normally would. Once the trace -is collected, it can the be read by babeltrace for analysis. - -Analysing the Trace -------------------- - -To perform the analysis, the trace can simply be read as it normally -would: - - $ babeltrace - -Debug info analysis is on by default and will automatically print the -extra source location information if it can find it. A sample output -may look like this: - - [...] - [16:18:15.845829429] (+0.000011697) colossus my_provider:my_first_tracepoint: { cpu_id = 2 }, { ip = 0x7F4D2A5D550E, debug_info = { bin = "libhello.so+0x150e", func = "foo+0xa9", src = "libhello.c:7" }, vpid = 28719 }, { my_string_field = "hello, tracer", my_integer_field = 42 } - [16:18:15.845841484] (+0.000012055) colossus my_provider:my_first_tracepoint: { cpu_id = 2 }, { ip = 0x7F4D2A5D55E0, debug_info = { bin = "libhello.so+0x15e0", func = "bar+0xa9", src = "libhello.c:13" }, vpid = 28719 }, { my_string_field = "recoltes et semailles", my_integer_field = 57 } - [16:18:15.845844852] (+0.000003368) colossus my_provider:my_other_tracepoint: { cpu_id = 2 }, { ip = 0x7F4D2A5D56A5, debug_info = { bin = "libhello.so+0x16a5", func = "baz+0x9c", src = "libhello.c:20" }, vpid = 28719 }, { some_field = 1729 } - [...] - -The interesting part is the debug_info section of the context: - - debug_info = { bin = "libhello.so+0x150e", func = "foo+0xa9", src = "libhello.c:7" } - -This is the expected output for events generated by an executable for -which DWARF information is available. It shows the name of the binary -and offset to the tracepoint, the name of the function containing the -tracepoint instance which generated the event ("foo") and the offset -within the function, and its source location ("libhello.c", line 7). - -The second event in the sample output is of the same type -("my_first_tracepoint"), but it was generated by a different -tracepoint instance, hence the different source location (line 13) and -function ("bar"). - -The third event, of a different type, also shows debug information. - -If DWARF info is absent, but ELF symbols are not stripped, the output -will instead look like this: - - [...] - [16:18:15.845829429] (+0.000011697) colossus my_provider:my_first_tracepoint: { cpu_id = 2 }, { ip = 0x7F4D2A5D550E, debug_info = { bin = "libhello.so+0x150e", func = "foo+0xa9" }, vpid = 28719 }, { my_string_field = "hello, tracer", my_integer_field = 42 } - [16:18:15.845841484] (+0.000012055) colossus my_provider:my_first_tracepoint: { cpu_id = 2 }, { ip = 0x7F4D2A5D55E0, debug_info = { bin = "libhello.so+0x15e0", func = "bar+0xa9" }, vpid = 28719 }, { my_string_field = "recoltes et semailles", my_integer_field = 57 } - [16:18:15.845844852] (+0.000003368) colossus my_provider:my_other_tracepoint: { cpu_id = 2 }, { ip = 0x7F4D2A5D56A5, debug_info = { bin = "libhello.so+0x16a5", func = "baz+0x9c" }, vpid = 28719 }, { some_field = 1729 } - [...] - -The debug information now provides both binary and function location -information, but no source location information, as this requires -DWARF. The function names are in fact resolved using ELF symbols, so -there may be a discrepancy with those provided by DWARF (e.g. in the -case of mangling). - -Paths to the binary and to the source location (if any) can be -expanded by using the command-line option ---debug-info-full-path. Otherwise, only the filename is shown. - -Debug Info and Dynamic Loading ------------------------------- - -Babeltrace can resolve addresses of events originating from -dynamically loaded libraries, provided that some extra information is -collected at tracing time. - -This can be achieved by preloading LTTng UST's libdl helper when -launching the program to be traced, like so: - - $ LD_PRELOAD="liblttng-ust-dl.so" - -The tracing and analysis can now be performed as described in prior -sections, and events from tracepoints in dlopened libraries will be -resolved automatically by babeltrace. - -Separate Debug Info -------------------- - -It is possible to store DWARF debug information separate from an -executable, whether for concerns of file size, or simply to facilitate -the sharing of the debug information. - -This is usually achieved via one of two mechanisms, namely build ID -and debug link. Both methods permit separate executables and debug -information. Their use and operation is described in GDB's -documentation at: - - https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html - -Babeltrace will find separate debug files automatically, provided they -follow the requirements described in the documentation above. The -debug information lookup order is the same as GDB's, that is first -debug info is looked for within the executable, then through the build -ID method in the standard /usr/lib/debug/.build-id/ location, and -finally in the various possible debug link locations. The first debug -information file found is used. - -The --debug-info-dir command-line option can be used to override the -default /usr/lib/debug/ directory used in build ID and debug link -lookups. Multiple debug info directories are currently not supported. - -Target Prefix -------------- - -The debug info analysis uses the paths to the executables as collected -during tracing as one mechanism to resolve DWARF or ELF -information. If the trace was taken on a separate machine, for -instance, it is possible to use --debug-info-target-prefix to specify -a prefix directory, representing the root of the target filesystem, -which will then be used for lookups. For example, if an executable was -located at /usr/bin/foo on the target system, it could be placed at -/home/efficios/target/usr/bin/foo on the system on which the analysis -is performed. In this case, the prefix is /home/efficios/target/. diff --git a/formats/ctf-text/Makefile.am b/formats/ctf-text/Makefile.am index d8180e85..f913de7a 100644 --- a/formats/ctf-text/Makefile.am +++ b/formats/ctf-text/Makefile.am @@ -15,6 +15,6 @@ libbabeltrace_ctf_text_la_LIBADD = \ $(top_builddir)/lib/libbabeltrace.la \ $(top_builddir)/formats/ctf/libbabeltrace-ctf.la -if ENABLE_DEBUGINFO -libbabeltrace_ctf_text_la_LIBADD += $(top_builddir)/lib/libdebuginfo.la +if ENABLE_DEBUG_INFO +libbabeltrace_ctf_text_la_LIBADD += $(top_builddir)/lib/libdebug-info.la endif diff --git a/formats/ctf-text/ctf-text.c b/formats/ctf-text/ctf-text.c index ddf41a54..cc22336c 100644 --- a/formats/ctf-text/ctf-text.c +++ b/formats/ctf-text/ctf-text.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/formats/ctf-text/types/integer.c b/formats/ctf-text/types/integer.c index f4d39256..ca0e5e60 100644 --- a/formats/ctf-text/types/integer.c +++ b/formats/ctf-text/types/integer.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include int ctf_text_integer_write(struct bt_stream_pos *ppos, struct bt_definition *definition) { diff --git a/formats/ctf/Makefile.am b/formats/ctf/Makefile.am index 19207bd7..909e59be 100644 --- a/formats/ctf/Makefile.am +++ b/formats/ctf/Makefile.am @@ -22,6 +22,6 @@ libbabeltrace_ctf_la_LIBADD = \ metadata/libctf-ast.la \ writer/libctf-writer.la -if ENABLE_DEBUGINFO -libbabeltrace_ctf_la_LIBADD += $(top_builddir)/lib/libdebuginfo.la +if ENABLE_DEBUG_INFO +libbabeltrace_ctf_la_LIBADD += $(top_builddir)/lib/libdebug-info.la endif diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index c960ef72..c5d654c9 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/Makefile.am b/include/Makefile.am index 39842e98..f6e8e492 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -33,8 +33,8 @@ noinst_HEADERS = \ babeltrace/prio_heap.h \ babeltrace/types.h \ babeltrace/crc32.h \ - babeltrace/debuginfo.h \ - babeltrace/trace-debuginfo.h \ + babeltrace/debug-info.h \ + babeltrace/trace-debug-info.h \ babeltrace/dwarf.h \ babeltrace/bin-info.h \ babeltrace/utils.h \ diff --git a/include/babeltrace/ctf-ir/metadata.h b/include/babeltrace/ctf-ir/metadata.h index 80033ff4..07706bb1 100644 --- a/include/babeltrace/ctf-ir/metadata.h +++ b/include/babeltrace/ctf-ir/metadata.h @@ -187,7 +187,7 @@ struct ctf_tracer_env { char tracer_name[TRACER_ENV_LEN]; }; -#ifdef ENABLE_DEBUGINFO +#ifdef ENABLE_DEBUG_INFO struct debug_info; #endif @@ -230,7 +230,7 @@ struct ctf_trace { int dirfd; int flags; /* open flags */ -#ifdef ENABLE_DEBUGINFO +#ifdef ENABLE_DEBUG_INFO /* Debug information for this trace */ struct debug_info *debug_info; #endif diff --git a/include/babeltrace/debug-info.h b/include/babeltrace/debug-info.h new file mode 100644 index 00000000..029b44f1 --- /dev/null +++ b/include/babeltrace/debug-info.h @@ -0,0 +1,82 @@ +#ifndef _BABELTRACE_DEBUG_INFO_H +#define _BABELTRACE_DEBUG_INFO_H + +/* + * Babeltrace - Debug information state tracker + * + * Copyright (c) 2015 EfficiOS Inc. + * Copyright (c) 2015 Philippe Proulx + * Copyright (c) 2015 Antoine Busque + * Copyright (c) 2016 Jérémie Galarneau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +struct debug_info; +struct ctf_event_definition; + +#ifdef ENABLE_DEBUG_INFO + +#include +#include +#include +#include + +struct debug_info_source { + /* Strings are owned by debug_info_source. */ + char *func; + uint64_t line_no; + char *src_path; + /* short_src_path points inside src_path, no need to free. */ + const char *short_src_path; + char *bin_path; + /* short_bin_path points inside bin_path, no need to free. */ + const char *short_bin_path; + /* + * Location within the binary. Either absolute (@0x1234) or + * relative (+0x4321). + */ + char *bin_loc; +}; + +BT_HIDDEN +struct debug_info *debug_info_create(void); + +BT_HIDDEN +void debug_info_destroy(struct debug_info *debug_info); + +BT_HIDDEN +void debug_info_handle_event(struct debug_info *debug_info, + struct ctf_event_definition *event); + +#else /* ifdef ENABLE_DEBUG_INFO */ + +static inline +struct debug_info *debug_info_create(void) { return malloc(1); } + +static inline +void debug_info_destroy(struct debug_info *debug_info) { free(debug_info); } + +static inline +void debug_info_handle_event(struct debug_info *debug_info, + struct ctf_event_definition *event) { } + +#endif /* ENABLE_DEBUG_INFO */ + +#endif /* _BABELTRACE_DEBUG_INFO_H */ diff --git a/include/babeltrace/debuginfo.h b/include/babeltrace/debuginfo.h deleted file mode 100644 index d85c36c4..00000000 --- a/include/babeltrace/debuginfo.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef _BABELTRACE_DEBUGINFO_H -#define _BABELTRACE_DEBUGINFO_H - -/* - * Babeltrace - Debug information state tracker - * - * Copyright (c) 2015 EfficiOS Inc. - * Copyright (c) 2015 Philippe Proulx - * Copyright (c) 2015 Antoine Busque - * Copyright (c) 2016 Jérémie Galarneau - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -struct debug_info; -struct ctf_event_definition; - -#ifdef ENABLE_DEBUGINFO - -#include -#include -#include -#include - -struct debug_info_source { - /* Strings are owned by debug_info_source. */ - char *func; - uint64_t line_no; - char *src_path; - /* short_src_path points inside src_path, no need to free. */ - const char *short_src_path; - char *bin_path; - /* short_bin_path points inside bin_path, no need to free. */ - const char *short_bin_path; - /* - * Location within the binary. Either absolute (@0x1234) or - * relative (+0x4321). - */ - char *bin_loc; -}; - -BT_HIDDEN -struct debug_info *debug_info_create(void); - -BT_HIDDEN -void debug_info_destroy(struct debug_info *debug_info); - -BT_HIDDEN -void debug_info_handle_event(struct debug_info *debug_info, - struct ctf_event_definition *event); - -#else /* ifdef ENABLE_DEBUGINFO */ - -static inline -struct debug_info *debug_info_create(void) { return malloc(1); } - -static inline -void debug_info_destroy(struct debug_info *debug_info) { free(debug_info); } - -static inline -void debug_info_handle_event(struct debug_info *debug_info, - struct ctf_event_definition *event) { } - -#endif /* ENABLE_DEBUGINFO */ - -#endif /* _BABELTRACE_DEBUGINFO_H */ diff --git a/include/babeltrace/trace-debug-info.h b/include/babeltrace/trace-debug-info.h new file mode 100644 index 00000000..451d54f5 --- /dev/null +++ b/include/babeltrace/trace-debug-info.h @@ -0,0 +1,157 @@ +#ifndef _BABELTRACE_TRACE_DEBUG_INFO_H +#define _BABELTRACE_TRACE_DEBUG_INFO_H + +/* + * Babeltrace - Debug information state tracker wrapper + * + * Copyright (c) 2015 EfficiOS Inc. + * Copyright (c) 2015 Antoine Busque + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include + +#ifdef ENABLE_DEBUG_INFO + +#include +#include +#include + +static inline +void ctf_text_integer_write_debug_info(struct bt_stream_pos *ppos, + struct bt_definition *definition) +{ + struct definition_integer *integer_definition = + container_of(definition, struct definition_integer, p); + struct ctf_text_stream_pos *pos = ctf_text_pos(ppos); + struct debug_info_source *debug_info_src = + integer_definition->debug_info_src; + + /* Print debug info if available */ + if (debug_info_src) { + if (debug_info_src->func || debug_info_src->src_path || + debug_info_src->bin_path) { + bool add_comma = false; + + fprintf(pos->fp, ", debug_info = { "); + + if (debug_info_src->bin_path) { + fprintf(pos->fp, "bin = \"%s%s\"", + opt_debug_info_full_path ? + debug_info_src->bin_path : + debug_info_src->short_bin_path, + debug_info_src->bin_loc); + add_comma = true; + } + + if (debug_info_src->func) { + if (add_comma) { + fprintf(pos->fp, ", "); + } + + fprintf(pos->fp, "func = \"%s\"", + debug_info_src->func); + } + + if (debug_info_src->src_path) { + if (add_comma) { + fprintf(pos->fp, ", "); + } + + fprintf(pos->fp, "src = \"%s:%" PRIu64 + "\"", + opt_debug_info_full_path ? + debug_info_src->src_path : + debug_info_src->short_src_path, + debug_info_src->line_no); + } + + fprintf(pos->fp, " }"); + } + } +} + +static inline +int trace_debug_info_create(struct ctf_trace *trace) +{ + int ret = 0; + + if (strcmp(trace->env.domain, "ust") != 0) { + goto end; + } + + if (strcmp(trace->env.tracer_name, "lttng-ust") != 0) { + goto end; + } + + trace->debug_info = debug_info_create(); + if (!trace->debug_info) { + ret = -1; + goto end; + } + +end: + return ret; +} + +static inline +void trace_debug_info_destroy(struct ctf_trace *trace) +{ + debug_info_destroy(trace->debug_info); +} + +static inline +void handle_debug_info_event(struct ctf_stream_declaration *stream_class, + struct ctf_event_definition *event) +{ + debug_info_handle_event(stream_class->trace->debug_info, event); +} + +#else /* #ifdef ENABLE_DEBUG_INFO */ + +static inline +void ctf_text_integer_write_debug_info(struct bt_stream_pos *ppos, + struct bt_definition *definition) +{ + /* Do nothing. */ +} + +static inline +int trace_debug_info_create(struct ctf_trace *trace) +{ + return 0; +} + +static inline +void trace_debug_info_destroy(struct ctf_trace *trace) +{ + /* Do nothing. */ +} + +static inline +void handle_debug_info_event(struct ctf_stream_declaration *stream_class, + struct ctf_event_definition *event) +{ + /* Do nothing. */ +} + +#endif /* #else #ifdef ENABLE_DEBUG_INFO */ + +#endif /* _BABELTRACE_TRACE_DEBUG_INFO_H */ diff --git a/include/babeltrace/trace-debuginfo.h b/include/babeltrace/trace-debuginfo.h deleted file mode 100644 index ed629231..00000000 --- a/include/babeltrace/trace-debuginfo.h +++ /dev/null @@ -1,157 +0,0 @@ -#ifndef _BABELTRACE_TRACE_DEBUGINFO_H -#define _BABELTRACE_TRACE_DEBUGINFO_H - -/* - * Babeltrace - Debug information state tracker wrapper - * - * Copyright (c) 2015 EfficiOS Inc. - * Copyright (c) 2015 Antoine Busque - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include - -#ifdef ENABLE_DEBUGINFO - -#include -#include -#include - -static inline -void ctf_text_integer_write_debug_info(struct bt_stream_pos *ppos, - struct bt_definition *definition) -{ - struct definition_integer *integer_definition = - container_of(definition, struct definition_integer, p); - struct ctf_text_stream_pos *pos = ctf_text_pos(ppos); - struct debug_info_source *debug_info_src = - integer_definition->debug_info_src; - - /* Print debug info if available */ - if (debug_info_src) { - if (debug_info_src->func || debug_info_src->src_path || - debug_info_src->bin_path) { - bool add_comma = false; - - fprintf(pos->fp, ", debug_info = { "); - - if (debug_info_src->bin_path) { - fprintf(pos->fp, "bin = \"%s%s\"", - opt_debug_info_full_path ? - debug_info_src->bin_path : - debug_info_src->short_bin_path, - debug_info_src->bin_loc); - add_comma = true; - } - - if (debug_info_src->func) { - if (add_comma) { - fprintf(pos->fp, ", "); - } - - fprintf(pos->fp, "func = \"%s\"", - debug_info_src->func); - } - - if (debug_info_src->src_path) { - if (add_comma) { - fprintf(pos->fp, ", "); - } - - fprintf(pos->fp, "src = \"%s:%" PRIu64 - "\"", - opt_debug_info_full_path ? - debug_info_src->src_path : - debug_info_src->short_src_path, - debug_info_src->line_no); - } - - fprintf(pos->fp, " }"); - } - } -} - -static inline -int trace_debug_info_create(struct ctf_trace *trace) -{ - int ret = 0; - - if (strcmp(trace->env.domain, "ust") != 0) { - goto end; - } - - if (strcmp(trace->env.tracer_name, "lttng-ust") != 0) { - goto end; - } - - trace->debug_info = debug_info_create(); - if (!trace->debug_info) { - ret = -1; - goto end; - } - -end: - return ret; -} - -static inline -void trace_debug_info_destroy(struct ctf_trace *trace) -{ - debug_info_destroy(trace->debug_info); -} - -static inline -void handle_debug_info_event(struct ctf_stream_declaration *stream_class, - struct ctf_event_definition *event) -{ - debug_info_handle_event(stream_class->trace->debug_info, event); -} - -#else /* #ifdef ENABLE_DEBUGINFO */ - -static inline -void ctf_text_integer_write_debug_info(struct bt_stream_pos *ppos, - struct bt_definition *definition) -{ - /* Do nothing. */ -} - -static inline -int trace_debug_info_create(struct ctf_trace *trace) -{ - return 0; -} - -static inline -void trace_debug_info_destroy(struct ctf_trace *trace) -{ - /* Do nothing. */ -} - -static inline -void handle_debug_info_event(struct ctf_stream_declaration *stream_class, - struct ctf_event_definition *event) -{ - /* Do nothing. */ -} - -#endif /* #else #ifdef ENABLE_DEBUGINFO */ - -#endif /* _BABELTRACE_TRACE_DEBUGINFO_H */ diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index 3d040d4f..e92fb842 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -148,7 +148,7 @@ struct declaration_integer { struct ctf_clock *clock; }; -#ifdef ENABLE_DEBUGINFO +#ifdef ENABLE_DEBUG_INFO struct debug_info_source; #endif @@ -161,7 +161,7 @@ struct definition_integer { int64_t _signed; } value; -#ifdef ENABLE_DEBUGINFO +#ifdef ENABLE_DEBUG_INFO /* * Debug infos (NULL if not set). * diff --git a/lib/Makefile.am b/lib/Makefile.am index 17a92f71..007abb78 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -13,16 +13,16 @@ libbabeltrace_la_SOURCES = babeltrace.c \ libbabeltrace_la_LDFLAGS = -version-info $(BABELTRACE_LIBRARY_VERSION) -if ENABLE_DEBUGINFO -noinst_LTLIBRARIES = libdebuginfo.la +if ENABLE_DEBUG_INFO +noinst_LTLIBRARIES = libdebug-info.la -libdebuginfo_la_SOURCES = debuginfo.c \ +libdebug_info_la_SOURCES = debug-info.c \ bin-info.c \ dwarf.c \ crc32.c \ utils.c -libdebuginfo_la_LDFLAGS = -lelf -ldw -libdebuginfo_la_LIBADD = libbabeltrace.la +libdebug_info_la_LDFLAGS = -lelf -ldw +libdebug_info_la_LIBADD = libbabeltrace.la endif libbabeltrace_la_LIBADD = \ diff --git a/lib/debug-info.c b/lib/debug-info.c new file mode 100644 index 00000000..cfb47f63 --- /dev/null +++ b/lib/debug-info.c @@ -0,0 +1,805 @@ +/* + * Babeltrace - Debug Information State Tracker + * + * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation + * Copyright (c) 2015 Philippe Proulx + * Copyright (c) 2015 Antoine Busque + * Copyright (c) 2016 Jérémie Galarneau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct proc_debug_info_sources { + /* + * Hash table: base address (pointer to uint64_t) to bin info; owned by + * proc_debug_info_sources. + */ + GHashTable *baddr_to_bin_info; + + /* + * Hash table: IP (pointer to uint64_t) to (struct debug_info_source *); + * owned by proc_debug_info_sources. + */ + GHashTable *ip_to_debug_info_src; +}; + +struct debug_info { + /* + * Hash table of VPIDs (pointer to int64_t) to + * (struct ctf_proc_debug_infos*); owned by debug_info. + */ + GHashTable *vpid_to_proc_dbg_info_src; + GQuark q_statedump_bin_info; + GQuark q_statedump_debug_link; + GQuark q_statedump_build_id; + GQuark q_statedump_start; + GQuark q_dl_open; +}; + +static +int debug_info_init(struct debug_info *info) +{ + info->q_statedump_bin_info = g_quark_from_string( + "lttng_ust_statedump:bin_info"); + info->q_statedump_debug_link = g_quark_from_string( + "lttng_ust_statedump:debug_link)"); + info->q_statedump_build_id = g_quark_from_string( + "lttng_ust_statedump:build_id"); + info->q_statedump_start = g_quark_from_string( + "lttng_ust_statedump:start"); + info->q_dl_open = g_quark_from_string("lttng_ust_dl:dlopen"); + + return bin_info_init(); +} + +static +void debug_info_source_destroy(struct debug_info_source *debug_info_src) +{ + if (!debug_info_src) { + return; + } + + free(debug_info_src->func); + free(debug_info_src->src_path); + free(debug_info_src->bin_path); + free(debug_info_src->bin_loc); + g_free(debug_info_src); +} + +static +struct debug_info_source *debug_info_source_create_from_bin(struct bin_info *bin, + uint64_t ip) +{ + int ret; + struct debug_info_source *debug_info_src = NULL; + struct source_location *src_loc = NULL; + + debug_info_src = g_new0(struct debug_info_source, 1); + + if (!debug_info_src) { + goto end; + } + + /* Lookup function name */ + ret = bin_info_lookup_function_name(bin, ip, &debug_info_src->func); + if (ret) { + goto error; + } + + /* Can't retrieve src_loc from ELF, or could not find binary, skip. */ + if (!bin->is_elf_only || !debug_info_src->func) { + /* Lookup source location */ + ret = bin_info_lookup_source_location(bin, ip, &src_loc); + printf_verbose("Failed to lookup source location (err: %i)\n", ret); + } + + if (src_loc) { + debug_info_src->line_no = src_loc->line_no; + + if (src_loc->filename) { + debug_info_src->src_path = strdup(src_loc->filename); + if (!debug_info_src->src_path) { + goto error; + } + + debug_info_src->short_src_path = get_filename_from_path( + debug_info_src->src_path); + } + + source_location_destroy(src_loc); + } + + if (bin->elf_path) { + debug_info_src->bin_path = strdup(bin->elf_path); + if (!debug_info_src->bin_path) { + goto error; + } + + debug_info_src->short_bin_path = get_filename_from_path( + debug_info_src->bin_path); + + ret = bin_info_get_bin_loc(bin, ip, &(debug_info_src->bin_loc)); + if (ret) { + goto error; + } + } + +end: + return debug_info_src; + +error: + debug_info_source_destroy(debug_info_src); + return NULL; +} + +static +void proc_debug_info_sources_destroy( + struct proc_debug_info_sources *proc_dbg_info_src) +{ + if (!proc_dbg_info_src) { + return; + } + + if (proc_dbg_info_src->baddr_to_bin_info) { + g_hash_table_destroy(proc_dbg_info_src->baddr_to_bin_info); + } + + if (proc_dbg_info_src->ip_to_debug_info_src) { + g_hash_table_destroy(proc_dbg_info_src->ip_to_debug_info_src); + } + + g_free(proc_dbg_info_src); +} + +static +struct proc_debug_info_sources *proc_debug_info_sources_create(void) +{ + struct proc_debug_info_sources *proc_dbg_info_src = NULL; + + proc_dbg_info_src = g_new0(struct proc_debug_info_sources, 1); + if (!proc_dbg_info_src) { + goto end; + } + + proc_dbg_info_src->baddr_to_bin_info = g_hash_table_new_full( + g_int64_hash, g_int64_equal, (GDestroyNotify) g_free, + (GDestroyNotify) bin_info_destroy); + if (!proc_dbg_info_src->baddr_to_bin_info) { + goto error; + } + + proc_dbg_info_src->ip_to_debug_info_src = g_hash_table_new_full( + g_int64_hash, g_int64_equal, (GDestroyNotify) g_free, + (GDestroyNotify) debug_info_source_destroy); + if (!proc_dbg_info_src->ip_to_debug_info_src) { + goto error; + } + +end: + return proc_dbg_info_src; + +error: + proc_debug_info_sources_destroy(proc_dbg_info_src); + return NULL; +} + +static +struct proc_debug_info_sources *proc_debug_info_sources_ht_get_entry( + GHashTable *ht, int64_t vpid) +{ + gpointer key = g_new0(int64_t, 1); + struct proc_debug_info_sources *proc_dbg_info_src = NULL; + + if (!key) { + goto end; + } + + *((int64_t *) key) = vpid; + + /* Exists? Return it */ + proc_dbg_info_src = g_hash_table_lookup(ht, key); + if (proc_dbg_info_src) { + goto end; + } + + /* Otherwise, create and return it */ + proc_dbg_info_src = proc_debug_info_sources_create(); + if (!proc_dbg_info_src) { + goto end; + } + + g_hash_table_insert(ht, key, proc_dbg_info_src); + /* Ownership passed to ht */ + key = NULL; +end: + g_free(key); + return proc_dbg_info_src; +} + +static +struct debug_info_source *proc_debug_info_sources_get_entry( + struct proc_debug_info_sources *proc_dbg_info_src, uint64_t ip) +{ + struct debug_info_source *debug_info_src = NULL; + gpointer key = g_new0(uint64_t, 1); + GHashTableIter iter; + gpointer baddr, value; + + if (!key) { + goto end; + } + + *((uint64_t *) key) = ip; + + /* Look in IP to debug infos hash table first. */ + debug_info_src = g_hash_table_lookup( + proc_dbg_info_src->ip_to_debug_info_src, + key); + if (debug_info_src) { + goto end; + } + + /* Check in all bin_infos. */ + g_hash_table_iter_init(&iter, proc_dbg_info_src->baddr_to_bin_info); + + while (g_hash_table_iter_next(&iter, &baddr, &value)) + { + struct bin_info *bin = value; + + if (!bin_info_has_address(value, ip)) { + continue; + } + + /* + * Found; add it to cache. + * + * FIXME: this should be bounded in size (and implement + * a caching policy), and entries should be prunned when + * libraries are unmapped. + */ + debug_info_src = debug_info_source_create_from_bin(bin, ip); + if (debug_info_src) { + g_hash_table_insert( + proc_dbg_info_src->ip_to_debug_info_src, + key, debug_info_src); + /* Ownership passed to ht. */ + key = NULL; + } + break; + } + +end: + free(key); + return debug_info_src; +} + +BT_HIDDEN +struct debug_info_source *debug_info_query(struct debug_info *debug_info, + int64_t vpid, uint64_t ip) +{ + struct debug_info_source *dbg_info_src = NULL; + struct proc_debug_info_sources *proc_dbg_info_src; + + proc_dbg_info_src = proc_debug_info_sources_ht_get_entry( + debug_info->vpid_to_proc_dbg_info_src, vpid); + if (!proc_dbg_info_src) { + goto end; + } + + dbg_info_src = proc_debug_info_sources_get_entry( + proc_dbg_info_src, ip); + if (!dbg_info_src) { + goto end; + } + +end: + return dbg_info_src; +} + +BT_HIDDEN +struct debug_info *debug_info_create(void) +{ + int ret; + struct debug_info *debug_info; + + debug_info = g_new0(struct debug_info, 1); + if (!debug_info) { + goto end; + } + + debug_info->vpid_to_proc_dbg_info_src = g_hash_table_new_full( + g_int64_hash, g_int64_equal, (GDestroyNotify) g_free, + (GDestroyNotify) proc_debug_info_sources_destroy); + if (!debug_info->vpid_to_proc_dbg_info_src) { + goto error; + } + + ret = debug_info_init(debug_info); + if (ret) { + goto error; + } + +end: + return debug_info; +error: + g_free(debug_info); + return NULL; +} + +BT_HIDDEN +void debug_info_destroy(struct debug_info *debug_info) +{ + if (!debug_info) { + goto end; + } + + if (debug_info->vpid_to_proc_dbg_info_src) { + g_hash_table_destroy(debug_info->vpid_to_proc_dbg_info_src); + } + + g_free(debug_info); +end: + return; +} + +static +void handle_statedump_build_id_event(struct debug_info *debug_info, + struct ctf_event_definition *event_def) +{ + struct proc_debug_info_sources *proc_dbg_info_src; + struct bt_definition *event_fields_def = NULL; + struct bt_definition *sec_def = NULL; + struct bt_definition *baddr_def = NULL; + struct bt_definition *vpid_def = NULL; + struct bt_definition *build_id_def = NULL; + struct definition_sequence *build_id_seq; + struct bin_info *bin = NULL; + int i; + int64_t vpid; + uint64_t baddr; + uint8_t *build_id = NULL; + uint64_t build_id_len; + + event_fields_def = (struct bt_definition *) event_def->event_fields; + sec_def = (struct bt_definition *) + event_def->stream->stream_event_context; + + if (!event_fields_def || !sec_def) { + goto end; + } + + baddr_def = bt_lookup_definition(event_fields_def, "_baddr"); + if (!baddr_def) { + goto end; + } + + vpid_def = bt_lookup_definition(sec_def, "_vpid"); + if (!vpid_def) { + goto end; + } + + build_id_def = bt_lookup_definition(event_fields_def, "_build_id"); + if (!build_id_def) { + goto end; + } + + if (baddr_def->declaration->id != CTF_TYPE_INTEGER) { + goto end; + } + + if (vpid_def->declaration->id != CTF_TYPE_INTEGER) { + goto end; + } + + if (build_id_def->declaration->id != CTF_TYPE_SEQUENCE) { + goto end; + } + + baddr = bt_get_unsigned_int(baddr_def); + vpid = bt_get_signed_int(vpid_def); + build_id_seq = container_of(build_id_def, + struct definition_sequence, p); + build_id_len = build_id_seq->length->value._unsigned; + + build_id = g_malloc(build_id_len); + if (!build_id) { + goto end; + } + + for (i = 0; i < build_id_len; ++i) { + struct bt_definition **field; + + field = (struct bt_definition **) &g_ptr_array_index( + build_id_seq->elems, i); + build_id[i] = bt_get_unsigned_int(*field); + } + + proc_dbg_info_src = proc_debug_info_sources_ht_get_entry( + debug_info->vpid_to_proc_dbg_info_src, vpid); + if (!proc_dbg_info_src) { + goto end; + } + + bin = g_hash_table_lookup(proc_dbg_info_src->baddr_to_bin_info, + (gpointer) &baddr); + if (!bin) { + /* + * The build_id event comes after the bin has been + * created. If it isn't found, just ignore this event. + */ + goto end; + } + + bin_info_set_build_id(bin, build_id, build_id_len); + +end: + free(build_id); + return; +} + +static +void handle_statedump_debug_link_event(struct debug_info *debug_info, + struct ctf_event_definition *event_def) +{ + struct proc_debug_info_sources *proc_dbg_info_src; + struct bt_definition *event_fields_def = NULL; + struct bt_definition *sec_def = NULL; + struct bt_definition *baddr_def = NULL; + struct bt_definition *vpid_def = NULL; + struct bt_definition *filename_def = NULL; + struct bt_definition *crc32_def = NULL; + struct bin_info *bin = NULL; + int64_t vpid; + uint64_t baddr; + char *filename = NULL; + uint32_t crc32; + + event_fields_def = (struct bt_definition *) event_def->event_fields; + sec_def = (struct bt_definition *) + event_def->stream->stream_event_context; + + if (!event_fields_def || !sec_def) { + goto end; + } + + baddr_def = bt_lookup_definition(event_fields_def, "_baddr"); + if (!baddr_def) { + goto end; + } + + vpid_def = bt_lookup_definition(sec_def, "_vpid"); + if (!vpid_def) { + goto end; + } + + filename_def = bt_lookup_definition(event_fields_def, "_filename"); + if (!filename_def) { + goto end; + } + + crc32_def = bt_lookup_definition(event_fields_def, "_crc32"); + if (!crc32_def) { + goto end; + } + + if (baddr_def->declaration->id != CTF_TYPE_INTEGER) { + goto end; + } + + if (vpid_def->declaration->id != CTF_TYPE_INTEGER) { + goto end; + } + + if (filename_def->declaration->id != CTF_TYPE_STRING) { + goto end; + } + + if (crc32_def->declaration->id != CTF_TYPE_INTEGER) { + goto end; + } + + baddr = bt_get_unsigned_int(baddr_def); + vpid = bt_get_signed_int(vpid_def); + + proc_dbg_info_src = proc_debug_info_sources_ht_get_entry( + debug_info->vpid_to_proc_dbg_info_src, vpid); + if (!proc_dbg_info_src) { + goto end; + } + + bin = g_hash_table_lookup(proc_dbg_info_src->baddr_to_bin_info, + (gpointer) &baddr); + if (!bin) { + /* + * The debug_link event comes after the bin has been + * created. If it isn't found, just ignore this event. + */ + goto end; + } + + filename = bt_get_string(filename_def); + crc32 = bt_get_unsigned_int(crc32_def); + + bin_info_set_debug_link(bin, filename, crc32); + +end: + return; +} + +static +void handle_bin_info_event(struct debug_info *debug_info, + struct ctf_event_definition *event_def, bool has_pic_field) +{ + struct bt_definition *baddr_def = NULL; + struct bt_definition *memsz_def = NULL; + struct bt_definition *path_def = NULL; + struct bt_definition *is_pic_def = NULL; + struct bt_definition *vpid_def = NULL; + struct bt_definition *event_fields_def = NULL; + struct bt_definition *sec_def = NULL; + struct proc_debug_info_sources *proc_dbg_info_src; + struct bin_info *bin; + uint64_t baddr, memsz; + int64_t vpid; + const char *path; + gpointer key = NULL; + bool is_pic; + + event_fields_def = (struct bt_definition *) event_def->event_fields; + sec_def = (struct bt_definition *) + event_def->stream->stream_event_context; + + if (!event_fields_def || !sec_def) { + goto end; + } + + baddr_def = bt_lookup_definition(event_fields_def, "_baddr"); + if (!baddr_def) { + goto end; + } + + memsz_def = bt_lookup_definition(event_fields_def, "_memsz"); + if (!memsz_def) { + goto end; + } + + path_def = bt_lookup_definition(event_fields_def, "_path"); + if (!path_def) { + goto end; + } + + if (has_pic_field) { + is_pic_def = bt_lookup_definition(event_fields_def, "_is_pic"); + if (!is_pic_def) { + goto end; + } + + if (is_pic_def->declaration->id != CTF_TYPE_INTEGER) { + goto end; + } + + is_pic = (bt_get_unsigned_int(is_pic_def) == 1); + } else { + /* + * dlopen has no is_pic field, because the shared + * object is always PIC. + */ + is_pic = true; + } + + vpid_def = bt_lookup_definition(sec_def, "_vpid"); + if (!vpid_def) { + goto end; + } + + if (baddr_def->declaration->id != CTF_TYPE_INTEGER) { + goto end; + } + + if (memsz_def->declaration->id != CTF_TYPE_INTEGER) { + goto end; + } + + if (path_def->declaration->id != CTF_TYPE_STRING) { + goto end; + } + + if (vpid_def->declaration->id != CTF_TYPE_INTEGER) { + goto end; + } + + baddr = bt_get_unsigned_int(baddr_def); + memsz = bt_get_unsigned_int(memsz_def); + path = bt_get_string(path_def); + vpid = bt_get_signed_int(vpid_def); + + if (!path) { + goto end; + } + + if (memsz == 0) { + /* Ignore VDSO. */ + goto end; + } + + proc_dbg_info_src = proc_debug_info_sources_ht_get_entry( + debug_info->vpid_to_proc_dbg_info_src, vpid); + if (!proc_dbg_info_src) { + goto end; + } + + key = g_new0(uint64_t, 1); + if (!key) { + goto end; + } + + *((uint64_t *) key) = baddr; + + bin = g_hash_table_lookup(proc_dbg_info_src->baddr_to_bin_info, + key); + if (bin) { + goto end; + } + + bin = bin_info_create(path, baddr, memsz, is_pic); + if (!bin) { + goto end; + } + + g_hash_table_insert(proc_dbg_info_src->baddr_to_bin_info, + key, bin); + /* Ownership passed to ht. */ + key = NULL; + +end: + g_free(key); + return; +} + +static inline +void handle_statedump_bin_info_event(struct debug_info *debug_info, + struct ctf_event_definition *event_def) +{ + handle_bin_info_event(debug_info, event_def, true); +} + +static inline +void handle_dlopen_event(struct debug_info *debug_info, + struct ctf_event_definition *event_def) +{ + handle_bin_info_event(debug_info, event_def, false); +} + + +static +void handle_statedump_start(struct debug_info *debug_info, + struct ctf_event_definition *event_def) +{ + struct bt_definition *vpid_def = NULL; + struct bt_definition *sec_def = NULL; + struct proc_debug_info_sources *proc_dbg_info_src; + int64_t vpid; + + sec_def = (struct bt_definition *) + event_def->stream->stream_event_context; + if (!sec_def) { + goto end; + } + + vpid_def = bt_lookup_definition(sec_def, "_vpid"); + if (!vpid_def) { + goto end; + } + + vpid = bt_get_signed_int(vpid_def); + + proc_dbg_info_src = proc_debug_info_sources_ht_get_entry( + debug_info->vpid_to_proc_dbg_info_src, vpid); + if (!proc_dbg_info_src) { + goto end; + } + + g_hash_table_remove_all(proc_dbg_info_src->baddr_to_bin_info); + g_hash_table_remove_all(proc_dbg_info_src->ip_to_debug_info_src); + +end: + return; +} + +static +void register_event_debug_infos(struct debug_info *debug_info, + struct ctf_event_definition *event) +{ + struct bt_definition *ip_def, *vpid_def; + int64_t vpid; + uint64_t ip; + struct bt_definition *sec_def; + + /* Get stream event context definition. */ + sec_def = (struct bt_definition *) event->stream->stream_event_context; + if (!sec_def) { + goto end; + } + + /* Get "ip" and "vpid" definitions. */ + vpid_def = bt_lookup_definition((struct bt_definition *) sec_def, + "_vpid"); + ip_def = bt_lookup_definition((struct bt_definition *) sec_def, "_ip"); + + if (!vpid_def || !ip_def) { + goto end; + } + + vpid = bt_get_signed_int(vpid_def); + ip = bt_get_unsigned_int(ip_def); + + /* Get debug info for this context. */ + ((struct definition_integer *) ip_def)->debug_info_src = + debug_info_query(debug_info, vpid, ip); + +end: + return; +} + +BT_HIDDEN +void debug_info_handle_event(struct debug_info *debug_info, + struct ctf_event_definition *event) +{ + struct ctf_event_declaration *event_class; + struct ctf_stream_declaration *stream_class; + + if (!debug_info || !event) { + goto end; + } + + stream_class = event->stream->stream_class; + event_class = g_ptr_array_index(stream_class->events_by_id, + event->stream->event_id); + + if (event_class->name == debug_info->q_statedump_bin_info) { + /* State dump */ + handle_statedump_bin_info_event(debug_info, event); + } else if (event_class->name == debug_info->q_dl_open) { + handle_dlopen_event(debug_info, event); + } else if (event_class->name == debug_info->q_statedump_start) { + /* Start state dump */ + handle_statedump_start(debug_info, event); + } else if (event_class->name == debug_info->q_statedump_debug_link) { + /* Debug link info */ + handle_statedump_debug_link_event(debug_info, event); + } else if (event_class->name == debug_info->q_statedump_build_id) { + /* Build ID info */ + handle_statedump_build_id_event(debug_info, event); + } else { + /* Other events: register debug infos */ + register_event_debug_infos(debug_info, event); + } + +end: + return; +} diff --git a/lib/debuginfo.c b/lib/debuginfo.c deleted file mode 100644 index 20c6fa01..00000000 --- a/lib/debuginfo.c +++ /dev/null @@ -1,805 +0,0 @@ -/* - * Babeltrace - Debug Information State Tracker - * - * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation - * Copyright (c) 2015 Philippe Proulx - * Copyright (c) 2015 Antoine Busque - * Copyright (c) 2016 Jérémie Galarneau - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -struct proc_debug_info_sources { - /* - * Hash table: base address (pointer to uint64_t) to bin info; owned by - * proc_debug_info_sources. - */ - GHashTable *baddr_to_bin_info; - - /* - * Hash table: IP (pointer to uint64_t) to (struct debug_info_source *); - * owned by proc_debug_info_sources. - */ - GHashTable *ip_to_debug_info_src; -}; - -struct debug_info { - /* - * Hash table of VPIDs (pointer to int64_t) to - * (struct ctf_proc_debug_infos*); owned by debug_info. - */ - GHashTable *vpid_to_proc_dbg_info_src; - GQuark q_statedump_bin_info; - GQuark q_statedump_debug_link; - GQuark q_statedump_build_id; - GQuark q_statedump_start; - GQuark q_dl_open; -}; - -static -int debug_info_init(struct debug_info *info) -{ - info->q_statedump_bin_info = g_quark_from_string( - "lttng_ust_statedump:bin_info"); - info->q_statedump_debug_link = g_quark_from_string( - "lttng_ust_statedump:debug_link)"); - info->q_statedump_build_id = g_quark_from_string( - "lttng_ust_statedump:build_id"); - info->q_statedump_start = g_quark_from_string( - "lttng_ust_statedump:start"); - info->q_dl_open = g_quark_from_string("lttng_ust_dl:dlopen"); - - return bin_info_init(); -} - -static -void debug_info_source_destroy(struct debug_info_source *debug_info_src) -{ - if (!debug_info_src) { - return; - } - - free(debug_info_src->func); - free(debug_info_src->src_path); - free(debug_info_src->bin_path); - free(debug_info_src->bin_loc); - g_free(debug_info_src); -} - -static -struct debug_info_source *debug_info_source_create_from_bin(struct bin_info *bin, - uint64_t ip) -{ - int ret; - struct debug_info_source *debug_info_src = NULL; - struct source_location *src_loc = NULL; - - debug_info_src = g_new0(struct debug_info_source, 1); - - if (!debug_info_src) { - goto end; - } - - /* Lookup function name */ - ret = bin_info_lookup_function_name(bin, ip, &debug_info_src->func); - if (ret) { - goto error; - } - - /* Can't retrieve src_loc from ELF, or could not find binary, skip. */ - if (!bin->is_elf_only || !debug_info_src->func) { - /* Lookup source location */ - ret = bin_info_lookup_source_location(bin, ip, &src_loc); - printf_verbose("Failed to lookup source location (err: %i)\n", ret); - } - - if (src_loc) { - debug_info_src->line_no = src_loc->line_no; - - if (src_loc->filename) { - debug_info_src->src_path = strdup(src_loc->filename); - if (!debug_info_src->src_path) { - goto error; - } - - debug_info_src->short_src_path = get_filename_from_path( - debug_info_src->src_path); - } - - source_location_destroy(src_loc); - } - - if (bin->elf_path) { - debug_info_src->bin_path = strdup(bin->elf_path); - if (!debug_info_src->bin_path) { - goto error; - } - - debug_info_src->short_bin_path = get_filename_from_path( - debug_info_src->bin_path); - - ret = bin_info_get_bin_loc(bin, ip, &(debug_info_src->bin_loc)); - if (ret) { - goto error; - } - } - -end: - return debug_info_src; - -error: - debug_info_source_destroy(debug_info_src); - return NULL; -} - -static -void proc_debug_info_sources_destroy( - struct proc_debug_info_sources *proc_dbg_info_src) -{ - if (!proc_dbg_info_src) { - return; - } - - if (proc_dbg_info_src->baddr_to_bin_info) { - g_hash_table_destroy(proc_dbg_info_src->baddr_to_bin_info); - } - - if (proc_dbg_info_src->ip_to_debug_info_src) { - g_hash_table_destroy(proc_dbg_info_src->ip_to_debug_info_src); - } - - g_free(proc_dbg_info_src); -} - -static -struct proc_debug_info_sources *proc_debug_info_sources_create(void) -{ - struct proc_debug_info_sources *proc_dbg_info_src = NULL; - - proc_dbg_info_src = g_new0(struct proc_debug_info_sources, 1); - if (!proc_dbg_info_src) { - goto end; - } - - proc_dbg_info_src->baddr_to_bin_info = g_hash_table_new_full( - g_int64_hash, g_int64_equal, (GDestroyNotify) g_free, - (GDestroyNotify) bin_info_destroy); - if (!proc_dbg_info_src->baddr_to_bin_info) { - goto error; - } - - proc_dbg_info_src->ip_to_debug_info_src = g_hash_table_new_full( - g_int64_hash, g_int64_equal, (GDestroyNotify) g_free, - (GDestroyNotify) debug_info_source_destroy); - if (!proc_dbg_info_src->ip_to_debug_info_src) { - goto error; - } - -end: - return proc_dbg_info_src; - -error: - proc_debug_info_sources_destroy(proc_dbg_info_src); - return NULL; -} - -static -struct proc_debug_info_sources *proc_debug_info_sources_ht_get_entry( - GHashTable *ht, int64_t vpid) -{ - gpointer key = g_new0(int64_t, 1); - struct proc_debug_info_sources *proc_dbg_info_src = NULL; - - if (!key) { - goto end; - } - - *((int64_t *) key) = vpid; - - /* Exists? Return it */ - proc_dbg_info_src = g_hash_table_lookup(ht, key); - if (proc_dbg_info_src) { - goto end; - } - - /* Otherwise, create and return it */ - proc_dbg_info_src = proc_debug_info_sources_create(); - if (!proc_dbg_info_src) { - goto end; - } - - g_hash_table_insert(ht, key, proc_dbg_info_src); - /* Ownership passed to ht */ - key = NULL; -end: - g_free(key); - return proc_dbg_info_src; -} - -static -struct debug_info_source *proc_debug_info_sources_get_entry( - struct proc_debug_info_sources *proc_dbg_info_src, uint64_t ip) -{ - struct debug_info_source *debug_info_src = NULL; - gpointer key = g_new0(uint64_t, 1); - GHashTableIter iter; - gpointer baddr, value; - - if (!key) { - goto end; - } - - *((uint64_t *) key) = ip; - - /* Look in IP to debug infos hash table first. */ - debug_info_src = g_hash_table_lookup( - proc_dbg_info_src->ip_to_debug_info_src, - key); - if (debug_info_src) { - goto end; - } - - /* Check in all bin_infos. */ - g_hash_table_iter_init(&iter, proc_dbg_info_src->baddr_to_bin_info); - - while (g_hash_table_iter_next(&iter, &baddr, &value)) - { - struct bin_info *bin = value; - - if (!bin_info_has_address(value, ip)) { - continue; - } - - /* - * Found; add it to cache. - * - * FIXME: this should be bounded in size (and implement - * a caching policy), and entries should be prunned when - * libraries are unmapped. - */ - debug_info_src = debug_info_source_create_from_bin(bin, ip); - if (debug_info_src) { - g_hash_table_insert( - proc_dbg_info_src->ip_to_debug_info_src, - key, debug_info_src); - /* Ownership passed to ht. */ - key = NULL; - } - break; - } - -end: - free(key); - return debug_info_src; -} - -BT_HIDDEN -struct debug_info_source *debug_info_query(struct debug_info *debug_info, - int64_t vpid, uint64_t ip) -{ - struct debug_info_source *dbg_info_src = NULL; - struct proc_debug_info_sources *proc_dbg_info_src; - - proc_dbg_info_src = proc_debug_info_sources_ht_get_entry( - debug_info->vpid_to_proc_dbg_info_src, vpid); - if (!proc_dbg_info_src) { - goto end; - } - - dbg_info_src = proc_debug_info_sources_get_entry( - proc_dbg_info_src, ip); - if (!dbg_info_src) { - goto end; - } - -end: - return dbg_info_src; -} - -BT_HIDDEN -struct debug_info *debug_info_create(void) -{ - int ret; - struct debug_info *debug_info; - - debug_info = g_new0(struct debug_info, 1); - if (!debug_info) { - goto end; - } - - debug_info->vpid_to_proc_dbg_info_src = g_hash_table_new_full( - g_int64_hash, g_int64_equal, (GDestroyNotify) g_free, - (GDestroyNotify) proc_debug_info_sources_destroy); - if (!debug_info->vpid_to_proc_dbg_info_src) { - goto error; - } - - ret = debug_info_init(debug_info); - if (ret) { - goto error; - } - -end: - return debug_info; -error: - g_free(debug_info); - return NULL; -} - -BT_HIDDEN -void debug_info_destroy(struct debug_info *debug_info) -{ - if (!debug_info) { - goto end; - } - - if (debug_info->vpid_to_proc_dbg_info_src) { - g_hash_table_destroy(debug_info->vpid_to_proc_dbg_info_src); - } - - g_free(debug_info); -end: - return; -} - -static -void handle_statedump_build_id_event(struct debug_info *debug_info, - struct ctf_event_definition *event_def) -{ - struct proc_debug_info_sources *proc_dbg_info_src; - struct bt_definition *event_fields_def = NULL; - struct bt_definition *sec_def = NULL; - struct bt_definition *baddr_def = NULL; - struct bt_definition *vpid_def = NULL; - struct bt_definition *build_id_def = NULL; - struct definition_sequence *build_id_seq; - struct bin_info *bin = NULL; - int i; - int64_t vpid; - uint64_t baddr; - uint8_t *build_id = NULL; - uint64_t build_id_len; - - event_fields_def = (struct bt_definition *) event_def->event_fields; - sec_def = (struct bt_definition *) - event_def->stream->stream_event_context; - - if (!event_fields_def || !sec_def) { - goto end; - } - - baddr_def = bt_lookup_definition(event_fields_def, "_baddr"); - if (!baddr_def) { - goto end; - } - - vpid_def = bt_lookup_definition(sec_def, "_vpid"); - if (!vpid_def) { - goto end; - } - - build_id_def = bt_lookup_definition(event_fields_def, "_build_id"); - if (!build_id_def) { - goto end; - } - - if (baddr_def->declaration->id != CTF_TYPE_INTEGER) { - goto end; - } - - if (vpid_def->declaration->id != CTF_TYPE_INTEGER) { - goto end; - } - - if (build_id_def->declaration->id != CTF_TYPE_SEQUENCE) { - goto end; - } - - baddr = bt_get_unsigned_int(baddr_def); - vpid = bt_get_signed_int(vpid_def); - build_id_seq = container_of(build_id_def, - struct definition_sequence, p); - build_id_len = build_id_seq->length->value._unsigned; - - build_id = g_malloc(build_id_len); - if (!build_id) { - goto end; - } - - for (i = 0; i < build_id_len; ++i) { - struct bt_definition **field; - - field = (struct bt_definition **) &g_ptr_array_index( - build_id_seq->elems, i); - build_id[i] = bt_get_unsigned_int(*field); - } - - proc_dbg_info_src = proc_debug_info_sources_ht_get_entry( - debug_info->vpid_to_proc_dbg_info_src, vpid); - if (!proc_dbg_info_src) { - goto end; - } - - bin = g_hash_table_lookup(proc_dbg_info_src->baddr_to_bin_info, - (gpointer) &baddr); - if (!bin) { - /* - * The build_id event comes after the bin has been - * created. If it isn't found, just ignore this event. - */ - goto end; - } - - bin_info_set_build_id(bin, build_id, build_id_len); - -end: - free(build_id); - return; -} - -static -void handle_statedump_debug_link_event(struct debug_info *debug_info, - struct ctf_event_definition *event_def) -{ - struct proc_debug_info_sources *proc_dbg_info_src; - struct bt_definition *event_fields_def = NULL; - struct bt_definition *sec_def = NULL; - struct bt_definition *baddr_def = NULL; - struct bt_definition *vpid_def = NULL; - struct bt_definition *filename_def = NULL; - struct bt_definition *crc32_def = NULL; - struct bin_info *bin = NULL; - int64_t vpid; - uint64_t baddr; - char *filename = NULL; - uint32_t crc32; - - event_fields_def = (struct bt_definition *) event_def->event_fields; - sec_def = (struct bt_definition *) - event_def->stream->stream_event_context; - - if (!event_fields_def || !sec_def) { - goto end; - } - - baddr_def = bt_lookup_definition(event_fields_def, "_baddr"); - if (!baddr_def) { - goto end; - } - - vpid_def = bt_lookup_definition(sec_def, "_vpid"); - if (!vpid_def) { - goto end; - } - - filename_def = bt_lookup_definition(event_fields_def, "_filename"); - if (!filename_def) { - goto end; - } - - crc32_def = bt_lookup_definition(event_fields_def, "_crc32"); - if (!crc32_def) { - goto end; - } - - if (baddr_def->declaration->id != CTF_TYPE_INTEGER) { - goto end; - } - - if (vpid_def->declaration->id != CTF_TYPE_INTEGER) { - goto end; - } - - if (filename_def->declaration->id != CTF_TYPE_STRING) { - goto end; - } - - if (crc32_def->declaration->id != CTF_TYPE_INTEGER) { - goto end; - } - - baddr = bt_get_unsigned_int(baddr_def); - vpid = bt_get_signed_int(vpid_def); - - proc_dbg_info_src = proc_debug_info_sources_ht_get_entry( - debug_info->vpid_to_proc_dbg_info_src, vpid); - if (!proc_dbg_info_src) { - goto end; - } - - bin = g_hash_table_lookup(proc_dbg_info_src->baddr_to_bin_info, - (gpointer) &baddr); - if (!bin) { - /* - * The debug_link event comes after the bin has been - * created. If it isn't found, just ignore this event. - */ - goto end; - } - - filename = bt_get_string(filename_def); - crc32 = bt_get_unsigned_int(crc32_def); - - bin_info_set_debug_link(bin, filename, crc32); - -end: - return; -} - -static -void handle_bin_info_event(struct debug_info *debug_info, - struct ctf_event_definition *event_def, bool has_pic_field) -{ - struct bt_definition *baddr_def = NULL; - struct bt_definition *memsz_def = NULL; - struct bt_definition *path_def = NULL; - struct bt_definition *is_pic_def = NULL; - struct bt_definition *vpid_def = NULL; - struct bt_definition *event_fields_def = NULL; - struct bt_definition *sec_def = NULL; - struct proc_debug_info_sources *proc_dbg_info_src; - struct bin_info *bin; - uint64_t baddr, memsz; - int64_t vpid; - const char *path; - gpointer key = NULL; - bool is_pic; - - event_fields_def = (struct bt_definition *) event_def->event_fields; - sec_def = (struct bt_definition *) - event_def->stream->stream_event_context; - - if (!event_fields_def || !sec_def) { - goto end; - } - - baddr_def = bt_lookup_definition(event_fields_def, "_baddr"); - if (!baddr_def) { - goto end; - } - - memsz_def = bt_lookup_definition(event_fields_def, "_memsz"); - if (!memsz_def) { - goto end; - } - - path_def = bt_lookup_definition(event_fields_def, "_path"); - if (!path_def) { - goto end; - } - - if (has_pic_field) { - is_pic_def = bt_lookup_definition(event_fields_def, "_is_pic"); - if (!is_pic_def) { - goto end; - } - - if (is_pic_def->declaration->id != CTF_TYPE_INTEGER) { - goto end; - } - - is_pic = (bt_get_unsigned_int(is_pic_def) == 1); - } else { - /* - * dlopen has no is_pic field, because the shared - * object is always PIC. - */ - is_pic = true; - } - - vpid_def = bt_lookup_definition(sec_def, "_vpid"); - if (!vpid_def) { - goto end; - } - - if (baddr_def->declaration->id != CTF_TYPE_INTEGER) { - goto end; - } - - if (memsz_def->declaration->id != CTF_TYPE_INTEGER) { - goto end; - } - - if (path_def->declaration->id != CTF_TYPE_STRING) { - goto end; - } - - if (vpid_def->declaration->id != CTF_TYPE_INTEGER) { - goto end; - } - - baddr = bt_get_unsigned_int(baddr_def); - memsz = bt_get_unsigned_int(memsz_def); - path = bt_get_string(path_def); - vpid = bt_get_signed_int(vpid_def); - - if (!path) { - goto end; - } - - if (memsz == 0) { - /* Ignore VDSO. */ - goto end; - } - - proc_dbg_info_src = proc_debug_info_sources_ht_get_entry( - debug_info->vpid_to_proc_dbg_info_src, vpid); - if (!proc_dbg_info_src) { - goto end; - } - - key = g_new0(uint64_t, 1); - if (!key) { - goto end; - } - - *((uint64_t *) key) = baddr; - - bin = g_hash_table_lookup(proc_dbg_info_src->baddr_to_bin_info, - key); - if (bin) { - goto end; - } - - bin = bin_info_create(path, baddr, memsz, is_pic); - if (!bin) { - goto end; - } - - g_hash_table_insert(proc_dbg_info_src->baddr_to_bin_info, - key, bin); - /* Ownership passed to ht. */ - key = NULL; - -end: - g_free(key); - return; -} - -static inline -void handle_statedump_bin_info_event(struct debug_info *debug_info, - struct ctf_event_definition *event_def) -{ - handle_bin_info_event(debug_info, event_def, true); -} - -static inline -void handle_dlopen_event(struct debug_info *debug_info, - struct ctf_event_definition *event_def) -{ - handle_bin_info_event(debug_info, event_def, false); -} - - -static -void handle_statedump_start(struct debug_info *debug_info, - struct ctf_event_definition *event_def) -{ - struct bt_definition *vpid_def = NULL; - struct bt_definition *sec_def = NULL; - struct proc_debug_info_sources *proc_dbg_info_src; - int64_t vpid; - - sec_def = (struct bt_definition *) - event_def->stream->stream_event_context; - if (!sec_def) { - goto end; - } - - vpid_def = bt_lookup_definition(sec_def, "_vpid"); - if (!vpid_def) { - goto end; - } - - vpid = bt_get_signed_int(vpid_def); - - proc_dbg_info_src = proc_debug_info_sources_ht_get_entry( - debug_info->vpid_to_proc_dbg_info_src, vpid); - if (!proc_dbg_info_src) { - goto end; - } - - g_hash_table_remove_all(proc_dbg_info_src->baddr_to_bin_info); - g_hash_table_remove_all(proc_dbg_info_src->ip_to_debug_info_src); - -end: - return; -} - -static -void register_event_debug_infos(struct debug_info *debug_info, - struct ctf_event_definition *event) -{ - struct bt_definition *ip_def, *vpid_def; - int64_t vpid; - uint64_t ip; - struct bt_definition *sec_def; - - /* Get stream event context definition. */ - sec_def = (struct bt_definition *) event->stream->stream_event_context; - if (!sec_def) { - goto end; - } - - /* Get "ip" and "vpid" definitions. */ - vpid_def = bt_lookup_definition((struct bt_definition *) sec_def, - "_vpid"); - ip_def = bt_lookup_definition((struct bt_definition *) sec_def, "_ip"); - - if (!vpid_def || !ip_def) { - goto end; - } - - vpid = bt_get_signed_int(vpid_def); - ip = bt_get_unsigned_int(ip_def); - - /* Get debug info for this context. */ - ((struct definition_integer *) ip_def)->debug_info_src = - debug_info_query(debug_info, vpid, ip); - -end: - return; -} - -BT_HIDDEN -void debug_info_handle_event(struct debug_info *debug_info, - struct ctf_event_definition *event) -{ - struct ctf_event_declaration *event_class; - struct ctf_stream_declaration *stream_class; - - if (!debug_info || !event) { - goto end; - } - - stream_class = event->stream->stream_class; - event_class = g_ptr_array_index(stream_class->events_by_id, - event->stream->event_id); - - if (event_class->name == debug_info->q_statedump_bin_info) { - /* State dump */ - handle_statedump_bin_info_event(debug_info, event); - } else if (event_class->name == debug_info->q_dl_open) { - handle_dlopen_event(debug_info, event); - } else if (event_class->name == debug_info->q_statedump_start) { - /* Start state dump */ - handle_statedump_start(debug_info, event); - } else if (event_class->name == debug_info->q_statedump_debug_link) { - /* Debug link info */ - handle_statedump_debug_link_event(debug_info, event); - } else if (event_class->name == debug_info->q_statedump_build_id) { - /* Build ID info */ - handle_statedump_build_id_event(debug_info, event); - } else { - /* Other events: register debug infos */ - register_event_debug_infos(debug_info, event); - } - -end: - return; -} diff --git a/tests/Makefile.am b/tests/Makefile.am index 98e0b85f..c64e4dec 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -13,10 +13,10 @@ TESTS = bin/test_trace_read \ lib/test_ctf_writer_complete EXTRA_DIST = $(srcdir)/ctf-traces/** \ - $(srcdir)/debuginfo-data/** \ - $(srcdir)/debuginfo-data/.build-id/cd/** + $(srcdir)/debug-info-data/** \ + $(srcdir)/debug-info-data/.build-id/cd/** -if ENABLE_DEBUGINFO +if ENABLE_DEBUG_INFO TESTS += lib/test_dwarf_complete \ lib/test_bin_info_complete endif diff --git a/tests/debug-info-data/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug b/tests/debug-info-data/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug new file mode 100644 index 00000000..aaeed269 Binary files /dev/null and b/tests/debug-info-data/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug differ diff --git a/tests/debug-info-data/README.md b/tests/debug-info-data/README.md new file mode 100644 index 00000000..6a4c36c3 --- /dev/null +++ b/tests/debug-info-data/README.md @@ -0,0 +1,64 @@ +debug-info-data +============== + +This directory contains pre-generated ELF and DWARF files used to test +the debug info analysis feature, including lookup of DWARF debugging +information via build ID and debug link methods, as well as the source +files used to generate them. + +The generated files are: + +* `libhello_so` (ELF and DWARF) +* `libhello_elf_so` (ELF only) +* `libhello_build_id_so` (ELF with separate DWARF via build ID) +* `libhello_debug_link_so` (ELF with separate DWARF via debug link) +* `libhello_debug_link_so.debug` (DWARF for debug link) +* `.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug` (DWARF for build ID) + +We use a suffix of "_so" instead of ".so" since some distributions +build systems will consider ".so" files as artifacts from a previous +build that were "left-over" and will remove them prior to the build. + +All files are generated from the four (4) following source files: + +* libhello.c +* libhello.h +* tp.c +* tp.h + +The generated executables were built using a GNU toolchain on an +x86_64 machine. + +To regenerate them, you can use follow these steps: + +## ELF and DWARF + + $ gcc -g -fPIC -c -I. tp.c libhello.c + $ gcc -shared -g -llttng-ust -ldl -Wl,-soname,libhello.so -o libhello_so tp.o libhello.o + +## ELF only + + $ gcc -fPIC -c -I. tp.c libhello.c + $ gcc -shared -llttng-ust -ldl -Wl,-soname,libhello_elf.so -o libhello_elf_so tp.o libhello.o + +## ELF and DWARF with Build ID + + $ gcc -g -fPIC -c -I. tp.c libhello.c + $ gcc -shared -g -llttng-ust -ldl -Wl,-soname,libhello_build_id.so -Wl,--build-id=sha1 -o libhello_build_id_so tp.o libhello.o + $ mkdir -p .build-id/cd/ + $ objcopy --only-keep-debug libhello_build_id_so .build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug + $ strip -g libhello_build_id_so + +The build ID might not be the same once the executable is regenerated +on your system, so adjust the values in the directory and file names +accordingly. Refer to the GDB documentation for more information: +https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html + +## ELF and DWARF with Debug Link + + $ gcc -g -fPIC -c -I. tp.c libhello.c + $ gcc -shared -g -llttng-ust -ldl -Wl,-soname,libhello_debug_link.so -o libhello_debug_link_so tp.o libhello.o + + $ objcopy --only-keep-debug libhello_debug_link_so libhello_debug_link_so.debug + $ strip -g libhello_debug_link_so + $ objcopy --add-gnu-debuglink=libhello_debug_link_so.debug libhello_debug_link_so diff --git a/tests/debug-info-data/libhello.c b/tests/debug-info-data/libhello.c new file mode 100644 index 00000000..95382b55 --- /dev/null +++ b/tests/debug-info-data/libhello.c @@ -0,0 +1,50 @@ +/* + * libhello.c + * + * Debug Info - Tests + * + * Copyright 2016 Antoine Busque + * + * Author: Antoine Busque + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#define TRACEPOINT_DEFINE +#include "tp.h" + +void foo() +{ + tracepoint(my_provider, my_first_tracepoint, 42, "hello, tracer"); + printf("foo\n"); +} + +void bar() +{ + tracepoint(my_provider, my_first_tracepoint, 57, + "recoltes et semailles"); + printf("bar\n"); +} + +void baz() +{ + tracepoint(my_provider, my_other_tracepoint, 1729); + printf("baz\n"); +} diff --git a/tests/debug-info-data/libhello.h b/tests/debug-info-data/libhello.h new file mode 100644 index 00000000..b3f8893e --- /dev/null +++ b/tests/debug-info-data/libhello.h @@ -0,0 +1,36 @@ +/* + * libhello.h + * + * Debug Info - Tests + * + * Copyright 2016 Antoine Busque + * + * Author: Antoine Busque + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _LIBHELLO_H +#define _LIBHELLO_H + +void foo(); +void bar(); +void baz(); + +#endif /* _LIBHELLO_H */ diff --git a/tests/debug-info-data/libhello_build_id_so b/tests/debug-info-data/libhello_build_id_so new file mode 100644 index 00000000..a5055ee7 Binary files /dev/null and b/tests/debug-info-data/libhello_build_id_so differ diff --git a/tests/debug-info-data/libhello_debug_link_so b/tests/debug-info-data/libhello_debug_link_so new file mode 100644 index 00000000..340c828e Binary files /dev/null and b/tests/debug-info-data/libhello_debug_link_so differ diff --git a/tests/debug-info-data/libhello_debug_link_so.debug b/tests/debug-info-data/libhello_debug_link_so.debug new file mode 100644 index 00000000..f2743c38 Binary files /dev/null and b/tests/debug-info-data/libhello_debug_link_so.debug differ diff --git a/tests/debug-info-data/libhello_elf_so b/tests/debug-info-data/libhello_elf_so new file mode 100644 index 00000000..9d1eb29a Binary files /dev/null and b/tests/debug-info-data/libhello_elf_so differ diff --git a/tests/debug-info-data/libhello_so b/tests/debug-info-data/libhello_so new file mode 100644 index 00000000..849f440a Binary files /dev/null and b/tests/debug-info-data/libhello_so differ diff --git a/tests/debug-info-data/tp.c b/tests/debug-info-data/tp.c new file mode 100644 index 00000000..e893355f --- /dev/null +++ b/tests/debug-info-data/tp.c @@ -0,0 +1,30 @@ +/* + * tp.c + * + * Debug Info - Tests + * + * Copyright 2016 Antoine Busque + * + * Author: Antoine Busque + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#define TRACEPOINT_CREATE_PROBES + +#include "tp.h" diff --git a/tests/debug-info-data/tp.h b/tests/debug-info-data/tp.h new file mode 100644 index 00000000..1a3660e8 --- /dev/null +++ b/tests/debug-info-data/tp.h @@ -0,0 +1,66 @@ +/* + * tp.h + * + * Debug Info - Tests + * + * Copyright 2016 Antoine Busque + * + * Author: Antoine Busque + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#undef TRACEPOINT_PROVIDER +#define TRACEPOINT_PROVIDER my_provider + +#undef TRACEPOINT_INCLUDE +#define TRACEPOINT_INCLUDE "./tp.h" + +#if !defined(_TP_H) || defined(TRACEPOINT_HEADER_MULTI_READ) +#define _TP_H + +#include + +TRACEPOINT_EVENT( + my_provider, + my_first_tracepoint, + TP_ARGS( + int, my_integer_arg, + char*, my_string_arg + ), + TP_FIELDS( + ctf_string(my_string_field, my_string_arg) + ctf_integer(int, my_integer_field, my_integer_arg) + ) +) + +TRACEPOINT_EVENT( + my_provider, + my_other_tracepoint, + TP_ARGS( + int, my_int + ), + TP_FIELDS( + ctf_integer(int, some_field, my_int) + ) +) + +#endif /* _TP_H */ + +#include diff --git a/tests/debuginfo-data/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug b/tests/debuginfo-data/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug deleted file mode 100644 index aaeed269..00000000 Binary files a/tests/debuginfo-data/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug and /dev/null differ diff --git a/tests/debuginfo-data/README.md b/tests/debuginfo-data/README.md deleted file mode 100644 index db131bc4..00000000 --- a/tests/debuginfo-data/README.md +++ /dev/null @@ -1,64 +0,0 @@ -debuginfo-data -============== - -This directory contains pre-generated ELF and DWARF files used to test -the debug-info analysis feature, including lookup of DWARF debugging -information via build ID and debug link methods, as well as the source -files used to generate them. - -The generated files are: - -* `libhello_so` (ELF and DWARF) -* `libhello_elf_so` (ELF only) -* `libhello_build_id_so` (ELF with separate DWARF via build ID) -* `libhello_debug_link_so` (ELF with separate DWARF via debug link) -* `libhello_debug_link_so.debug` (DWARF for debug link) -* `.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug` (DWARF for build ID) - -We use a suffix of "_so" instead of ".so" since some distributions -build systems will consider ".so" files as artifacts from a previous -build that were "left-over" and will remove them prior to the build. - -All files are generated from the four (4) following source files: - -* libhello.c -* libhello.h -* tp.c -* tp.h - -The generated executables were built using a GNU toolchain on an -x86_64 machine. - -To regenerate them, you can use follow these steps: - -## ELF and DWARF - - $ gcc -g -fPIC -c -I. tp.c libhello.c - $ gcc -shared -g -llttng-ust -ldl -Wl,-soname,libhello.so -o libhello_so tp.o libhello.o - -## ELF only - - $ gcc -fPIC -c -I. tp.c libhello.c - $ gcc -shared -llttng-ust -ldl -Wl,-soname,libhello_elf.so -o libhello_elf_so tp.o libhello.o - -## ELF and DWARF with Build ID - - $ gcc -g -fPIC -c -I. tp.c libhello.c - $ gcc -shared -g -llttng-ust -ldl -Wl,-soname,libhello_build_id.so -Wl,--build-id=sha1 -o libhello_build_id_so tp.o libhello.o - $ mkdir -p .build-id/cd/ - $ objcopy --only-keep-debug libhello_build_id_so .build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug - $ strip -g libhello_build_id_so - -The build ID might not be the same once the executable is regenerated -on your system, so adjust the values in the directory and file names -accordingly. Refer to the GDB documentation for more information: -https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html - -## ELF and DWARF with Debug Link - - $ gcc -g -fPIC -c -I. tp.c libhello.c - $ gcc -shared -g -llttng-ust -ldl -Wl,-soname,libhello_debug_link.so -o libhello_debug_link_so tp.o libhello.o - - $ objcopy --only-keep-debug libhello_debug_link_so libhello_debug_link_so.debug - $ strip -g libhello_debug_link_so - $ objcopy --add-gnu-debuglink=libhello_debug_link_so.debug libhello_debug_link_so diff --git a/tests/debuginfo-data/libhello.c b/tests/debuginfo-data/libhello.c deleted file mode 100644 index 95382b55..00000000 --- a/tests/debuginfo-data/libhello.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * libhello.c - * - * Debug Info - Tests - * - * Copyright 2016 Antoine Busque - * - * Author: Antoine Busque - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#define TRACEPOINT_DEFINE -#include "tp.h" - -void foo() -{ - tracepoint(my_provider, my_first_tracepoint, 42, "hello, tracer"); - printf("foo\n"); -} - -void bar() -{ - tracepoint(my_provider, my_first_tracepoint, 57, - "recoltes et semailles"); - printf("bar\n"); -} - -void baz() -{ - tracepoint(my_provider, my_other_tracepoint, 1729); - printf("baz\n"); -} diff --git a/tests/debuginfo-data/libhello.h b/tests/debuginfo-data/libhello.h deleted file mode 100644 index b3f8893e..00000000 --- a/tests/debuginfo-data/libhello.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * libhello.h - * - * Debug Info - Tests - * - * Copyright 2016 Antoine Busque - * - * Author: Antoine Busque - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _LIBHELLO_H -#define _LIBHELLO_H - -void foo(); -void bar(); -void baz(); - -#endif /* _LIBHELLO_H */ diff --git a/tests/debuginfo-data/libhello_build_id_so b/tests/debuginfo-data/libhello_build_id_so deleted file mode 100644 index a5055ee7..00000000 Binary files a/tests/debuginfo-data/libhello_build_id_so and /dev/null differ diff --git a/tests/debuginfo-data/libhello_debug_link_so b/tests/debuginfo-data/libhello_debug_link_so deleted file mode 100644 index 340c828e..00000000 Binary files a/tests/debuginfo-data/libhello_debug_link_so and /dev/null differ diff --git a/tests/debuginfo-data/libhello_debug_link_so.debug b/tests/debuginfo-data/libhello_debug_link_so.debug deleted file mode 100644 index f2743c38..00000000 Binary files a/tests/debuginfo-data/libhello_debug_link_so.debug and /dev/null differ diff --git a/tests/debuginfo-data/libhello_elf_so b/tests/debuginfo-data/libhello_elf_so deleted file mode 100644 index 9d1eb29a..00000000 Binary files a/tests/debuginfo-data/libhello_elf_so and /dev/null differ diff --git a/tests/debuginfo-data/libhello_so b/tests/debuginfo-data/libhello_so deleted file mode 100644 index 849f440a..00000000 Binary files a/tests/debuginfo-data/libhello_so and /dev/null differ diff --git a/tests/debuginfo-data/tp.c b/tests/debuginfo-data/tp.c deleted file mode 100644 index e893355f..00000000 --- a/tests/debuginfo-data/tp.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * tp.c - * - * Debug Info - Tests - * - * Copyright 2016 Antoine Busque - * - * Author: Antoine Busque - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#define TRACEPOINT_CREATE_PROBES - -#include "tp.h" diff --git a/tests/debuginfo-data/tp.h b/tests/debuginfo-data/tp.h deleted file mode 100644 index 1a3660e8..00000000 --- a/tests/debuginfo-data/tp.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * tp.h - * - * Debug Info - Tests - * - * Copyright 2016 Antoine Busque - * - * Author: Antoine Busque - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#undef TRACEPOINT_PROVIDER -#define TRACEPOINT_PROVIDER my_provider - -#undef TRACEPOINT_INCLUDE -#define TRACEPOINT_INCLUDE "./tp.h" - -#if !defined(_TP_H) || defined(TRACEPOINT_HEADER_MULTI_READ) -#define _TP_H - -#include - -TRACEPOINT_EVENT( - my_provider, - my_first_tracepoint, - TP_ARGS( - int, my_integer_arg, - char*, my_string_arg - ), - TP_FIELDS( - ctf_string(my_string_field, my_string_arg) - ctf_integer(int, my_integer_field, my_integer_arg) - ) -) - -TRACEPOINT_EVENT( - my_provider, - my_other_tracepoint, - TP_ARGS( - int, my_int - ), - TP_FIELDS( - ctf_integer(int, some_field, my_int) - ) -) - -#endif /* _TP_H */ - -#include diff --git a/tests/lib/Makefile.am b/tests/lib/Makefile.am index 10fd9e73..33ada161 100644 --- a/tests/lib/Makefile.am +++ b/tests/lib/Makefile.am @@ -30,17 +30,17 @@ check_SCRIPTS = test_seek_big_trace \ test_seek_empty_packet \ test_ctf_writer_complete -if ENABLE_DEBUGINFO +if ENABLE_DEBUG_INFO test_dwarf_LDFLAGS = -static test_dwarf_LDADD = $(LIBTAP) \ $(top_builddir)/lib/libbabeltrace.la \ - $(top_builddir)/lib/libdebuginfo.la + $(top_builddir)/lib/libdebug-info.la test_dwarf_SOURCES = test_dwarf.c test_bin_info_LDFLAGS = -static test_bin_info_LDADD = $(LIBTAP) \ $(top_builddir)/lib/libbabeltrace.la \ - $(top_builddir)/lib/libdebuginfo.la + $(top_builddir)/lib/libdebug-info.la test_bin_info_SOURCES = test_bin_info.c noinst_PROGRAMS += test_dwarf test_bin_info diff --git a/tests/lib/test_bin_info_complete.in b/tests/lib/test_bin_info_complete.in index bcf4be2d..3ca7ca23 100755 --- a/tests/lib/test_bin_info_complete.in +++ b/tests/lib/test_bin_info_complete.in @@ -17,6 +17,6 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # -DEBUGINFO_DATA="@abs_top_srcdir@/tests/debuginfo-data" +DEBUG_INFO_DATA="@abs_top_srcdir@/tests/debug-info-data" -"@abs_top_builddir@/tests/lib/test_bin_info" "$DEBUGINFO_DATA" +"@abs_top_builddir@/tests/lib/test_bin_info" "$DEBUG_INFO_DATA" diff --git a/tests/lib/test_dwarf_complete.in b/tests/lib/test_dwarf_complete.in index d5b94f6c..a3f026d6 100755 --- a/tests/lib/test_dwarf_complete.in +++ b/tests/lib/test_dwarf_complete.in @@ -17,6 +17,6 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # -DEBUGINFO_DATA="@abs_top_srcdir@/tests/debuginfo-data" +DEBUG_INFO_DATA="@abs_top_srcdir@/tests/debug-info-data" -"@abs_top_builddir@/tests/lib/test_dwarf" "$DEBUGINFO_DATA" +"@abs_top_builddir@/tests/lib/test_dwarf" "$DEBUG_INFO_DATA"