summaryrefslogtreecommitdiffstats
path: root/tests/backtrace.c
diff options
context:
space:
mode:
authorUlf Hermann <[email protected]>2017-02-10 15:19:40 +0100
committerMark Wielaard <[email protected]>2017-02-14 10:24:36 +0100
commitf9971cb422df39adea7e8c7e22689b879e39c626 (patch)
tree4fbdcd948d9b476478b9f5d8cd3bf41fb8e092b3 /tests/backtrace.c
parenta9d7469866726dc460b1b47d5619a4fa72977c9a (diff)
Optionally allow unknown symbols in the backtrace tests
This is useful to test unwinding without debug information. The binaries being examined might still have frame pointers that allow us to bridge the unknown symbols. Signed-off-by: Ulf Hermann <[email protected]>
Diffstat (limited to 'tests/backtrace.c')
-rw-r--r--tests/backtrace.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/tests/backtrace.c b/tests/backtrace.c
index 1ff6353c..34a2ab0b 100644
--- a/tests/backtrace.c
+++ b/tests/backtrace.c
@@ -64,6 +64,7 @@ dump_modules (Dwfl_Module *mod, void **userdata __attribute__ ((unused)),
return DWARF_CB_OK;
}
+static bool allow_unknown;
static bool use_raise_jmp_patching;
static pid_t check_tid;
@@ -78,7 +79,8 @@ callback_verify (pid_t tid, unsigned frameno, Dwarf_Addr pc,
seen_main = true;
if (pc == 0)
{
- assert (seen_main);
+ if (!allow_unknown)
+ assert (seen_main);
return;
}
if (check_tid == 0)
@@ -103,11 +105,12 @@ callback_verify (pid_t tid, unsigned frameno, Dwarf_Addr pc,
&& (strcmp (symname, "__kernel_vsyscall") == 0
|| strcmp (symname, "__libc_do_syscall") == 0))
reduce_frameno = true;
- else
+ else if (!allow_unknown || symname)
assert (symname && strcmp (symname, "raise") == 0);
break;
case 1:
- assert (symname != NULL && strcmp (symname, "sigusr2") == 0);
+ if (!allow_unknown || symname)
+ assert (symname != NULL && strcmp (symname, "sigusr2") == 0);
break;
case 2: // x86_64 only
/* __restore_rt - glibc maybe does not have to have this symbol. */
@@ -116,20 +119,24 @@ callback_verify (pid_t tid, unsigned frameno, Dwarf_Addr pc,
if (use_raise_jmp_patching)
{
/* Verify we trapped on the very first instruction of jmp. */
- assert (symname != NULL && strcmp (symname, "jmp") == 0);
+ if (!allow_unknown || symname)
+ assert (symname != NULL && strcmp (symname, "jmp") == 0);
mod = dwfl_addrmodule (dwfl, pc - 1);
if (mod)
symname2 = dwfl_module_addrname (mod, pc - 1);
- assert (symname2 == NULL || strcmp (symname2, "jmp") != 0);
+ if (!allow_unknown || symname2)
+ assert (symname2 == NULL || strcmp (symname2, "jmp") != 0);
break;
}
/* FALLTHRU */
case 4:
- assert (symname != NULL && strcmp (symname, "stdarg") == 0);
+ if (!allow_unknown || symname)
+ assert (symname != NULL && strcmp (symname, "stdarg") == 0);
break;
case 5:
/* Verify we trapped on the very last instruction of child. */
- assert (symname != NULL && strcmp (symname, "backtracegen") == 0);
+ if (!allow_unknown || symname)
+ assert (symname != NULL && strcmp (symname, "backtracegen") == 0);
mod = dwfl_addrmodule (dwfl, pc);
if (mod)
symname2 = dwfl_module_addrname (mod, pc);
@@ -138,7 +145,7 @@ callback_verify (pid_t tid, unsigned frameno, Dwarf_Addr pc,
// there is no guarantee that the compiler doesn't reorder the
// instructions or even inserts some padding instructions at the end
// (which apparently happens on ppc64).
- if (use_raise_jmp_patching)
+ if (use_raise_jmp_patching && (!allow_unknown || symname2))
assert (symname2 == NULL || strcmp (symname2, "backtracegen") != 0);
break;
}
@@ -424,10 +431,12 @@ exec_dump (const char *exec)
}
#define OPT_BACKTRACE_EXEC 0x100
+#define OPT_ALLOW_UNKNOWN 0x200
static const struct argp_option options[] =
{
{ "backtrace-exec", OPT_BACKTRACE_EXEC, "EXEC", 0, N_("Run executable"), 0 },
+ { "allow-unknown", OPT_ALLOW_UNKNOWN, 0, 0, N_("Allow unknown symbols"), 0 },
{ NULL, 0, NULL, 0, NULL, 0 }
};
@@ -445,6 +454,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
exec_dump (arg);
exit (0);
+ case OPT_ALLOW_UNKNOWN:
+ allow_unknown = true;
+ break;
+
default:
return ARGP_ERR_UNKNOWN;
}
@@ -463,6 +476,7 @@ main (int argc __attribute__ ((unused)), char **argv)
(void) setlocale (LC_ALL, "");
elf_version (EV_CURRENT);
+ allow_unknown = false;
Dwfl *dwfl = NULL;
const struct argp_child argp_children[] =