summaryrefslogtreecommitdiff
path: root/tests/backtrace.c
diff options
context:
space:
mode:
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[] =