From beef86dc741318692ee1affa5a733a0ec4d6fd3d Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Mon, 18 Apr 2016 09:33:14 -0400 Subject: [PATCH] Print "binary+offset" when function name can't be resolved MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérémie Galarneau --- include/Makefile.am | 1 + include/babeltrace/utils.h | 39 ++++++++++++++++++++++++++++ lib/Makefile.am | 7 ++--- lib/debuginfo.c | 32 +---------------------- lib/so-info.c | 36 ++++++++++++++++++-------- lib/utils.c | 52 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 123 insertions(+), 44 deletions(-) create mode 100644 include/babeltrace/utils.h create mode 100644 lib/utils.c diff --git a/include/Makefile.am b/include/Makefile.am index 1f2b558a..ba6d9127 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -37,6 +37,7 @@ noinst_HEADERS = \ babeltrace/trace-debuginfo.h \ babeltrace/dwarf.h \ babeltrace/so-info.h \ + babeltrace/utils.h \ babeltrace/ctf-ir/metadata.h \ babeltrace/ctf/events-internal.h \ babeltrace/ctf/metadata.h \ diff --git a/include/babeltrace/utils.h b/include/babeltrace/utils.h new file mode 100644 index 00000000..d2a08c06 --- /dev/null +++ b/include/babeltrace/utils.h @@ -0,0 +1,39 @@ +#ifndef _BABELTRACE_DEBUG_INFO_UTILS_H +#define _BABELTRACE_DEBUG_INFO_UTILS_H + +/* + * Babeltrace - Debug Info Utilities + * + * Copyright 2016 Jérémie Galarneau + * + * Author: 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 + +/* + * Return the location of a path's file (the last element of the path). + * Returns the original path on error. + */ +BT_HIDDEN +const char *get_filename_from_path(const char *path); + +#endif /* _BABELTRACE_DEBUG_INFO_UTILS_H */ diff --git a/lib/Makefile.am b/lib/Makefile.am index 42a94346..d878e5fa 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -17,9 +17,10 @@ if ENABLE_DEBUGINFO noinst_LTLIBRARIES = libdebuginfo.la libdebuginfo_la_SOURCES = debuginfo.c \ - so-info.c \ - dwarf.c \ - crc32.c + so-info.c \ + dwarf.c \ + crc32.c \ + utils.c libdebuginfo_la_LDFLAGS = -lelf -ldw endif diff --git a/lib/debuginfo.c b/lib/debuginfo.c index 7d12ebd2..a2b94e2f 100644 --- a/lib/debuginfo.c +++ b/lib/debuginfo.c @@ -32,6 +32,7 @@ #include #include #include +#include struct proc_debug_info_sources { /* @@ -89,37 +90,6 @@ void debug_info_source_destroy(struct debug_info_source *debug_info_src) g_free(debug_info_src); } -/* - * Returns the location of a path's file (the last element of the path). - * Returns the original path on error. - */ -static -const char *get_filename_from_path(const char *path) -{ - size_t i = strlen(path); - - if (i == 0) { - goto end; - } - - if (path[i - 1] == '/') { - /* - * Path ends with a trailing slash, no filename to return. - * Return the original path. - */ - goto end; - } - - while (i-- > 0) { - if (path[i] == '/') { - path = &path[i + 1]; - goto end; - } - } -end: - return path; -} - static struct debug_info_source *debug_info_source_create_from_so(struct so_info *so, uint64_t ip) diff --git a/lib/so-info.c b/lib/so-info.c index 404425dc..83ddccc8 100644 --- a/lib/so-info.c +++ b/lib/so-info.c @@ -40,6 +40,7 @@ #include #include #include +#include /* * An address printed in hex is at most 20 bytes (16 for 64-bits + @@ -826,11 +827,12 @@ error: } BT_HIDDEN -int so_info_lookup_function_name(struct so_info *so, uint64_t addr, +int so_info_lookup_function_name(struct so_info *so, uint64_t ip, char **func_name) { int ret = 0; char *_func_name = NULL; + uint64_t relative_addr; if (!so || !func_name) { goto error; @@ -845,32 +847,46 @@ int so_info_lookup_function_name(struct so_info *so, uint64_t addr, } } - if (!so_info_has_address(so, addr)) { + if (!so_info_has_address(so, ip)) { goto error; } + relative_addr = ip - so->low_addr; /* * Addresses in ELF and DWARF are relative to base address for * PIC, so make the address argument relative too if needed. */ - if (so->is_pic) { - addr -= so->low_addr; - } - if (so->is_elf_only) { - ret = so_info_lookup_elf_function_name(so, addr, &_func_name); + ret = so_info_lookup_elf_function_name(so, + so->is_pic ? relative_addr : ip, + &_func_name); } else { - ret = so_info_lookup_dwarf_function_name(so, addr, &_func_name); + ret = so_info_lookup_dwarf_function_name(so, + so->is_pic ? relative_addr : ip, + &_func_name); } if (ret) { goto error; } - if (_func_name) { - *func_name = _func_name; + if (!_func_name) { + /* + * Can't map to a function; fallback to a generic output of the + * form binary+/@address. + * + * FIXME check position independence flag. + */ + const char *binary_name = get_filename_from_path(so->elf_path); + + ret = asprintf(&_func_name, "%s+%#0" PRIx64, binary_name, + relative_addr); + if (!_func_name) { + goto error; + } } + *func_name = _func_name; return 0; error: diff --git a/lib/utils.c b/lib/utils.c new file mode 100644 index 00000000..259b160f --- /dev/null +++ b/lib/utils.c @@ -0,0 +1,52 @@ +/* + * Babeltrace - Debug info utilities + * + * 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 + +BT_HIDDEN +const char *get_filename_from_path(const char *path) +{ + size_t i = strlen(path); + + if (i == 0) { + goto end; + } + + if (path[i - 1] == '/') { + /* + * Path ends with a trailing slash, no filename to return. + * Return the original path. + */ + goto end; + } + + while (i-- > 0) { + if (path[i] == '/') { + path = &path[i + 1]; + goto end; + } + } +end: + return path; +} -- 2.34.1