mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2025-02-17 02:31:41 +01:00
2007-04-05 Jan Kratochvil <jan.kratochvil@redhat.com>
* tests/test-ptrace.c (target_pid_kill): New function. (target_pid, main): TARGET_PID made static, for target_pid_kill (). (main): Register target_pid_kill () for atexit(3). 2007-04-04 Jan Kratochvil <jan.kratochvil@redhat.com> * tests/Gtest-dyn1.c, tests/test-async-sig.c, tests/test-ptrace.c: Fixed lockups on broken libunwind (as ppc64 is). 2007-03-07 Jan Kratochvil <jan.kratochvil@redhat.com> * tests/test-async-sig.c (do_backtrace): Limit maximum backtrace depth to 100 iterations; it workarounds FC6 DWARF-broken glibc. 2006-12-10 Jan Kratochvil <jan.kratochvil@redhat.com> * tests/test-ptrace.c (main): Check for too many unexpected child signals, such as the common `SIGSEGV'.
This commit is contained in:
parent
7923ae31a0
commit
a72abd4e46
3 changed files with 70 additions and 8 deletions
|
@ -87,7 +87,7 @@ sighandler (int signal)
|
||||||
char name[128], off[32];
|
char name[128], off[32];
|
||||||
unw_word_t ip, offset;
|
unw_word_t ip, offset;
|
||||||
unw_context_t uc;
|
unw_context_t uc;
|
||||||
int count = 0;
|
int count;
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf ("caught signal %d\n", signal);
|
printf ("caught signal %d\n", signal);
|
||||||
|
@ -95,11 +95,21 @@ sighandler (int signal)
|
||||||
unw_getcontext (&uc);
|
unw_getcontext (&uc);
|
||||||
unw_init_local (&cursor, &uc);
|
unw_init_local (&cursor, &uc);
|
||||||
|
|
||||||
|
count = 0;
|
||||||
while (!unw_is_signal_frame (&cursor))
|
while (!unw_is_signal_frame (&cursor))
|
||||||
|
{
|
||||||
if (unw_step (&cursor) < 0)
|
if (unw_step (&cursor) < 0)
|
||||||
panic ("failed to find signal frame!\n");
|
panic ("failed to find signal frame!\n");
|
||||||
|
|
||||||
|
if (count++ > 20)
|
||||||
|
{
|
||||||
|
panic ("Too many steps to the signal frame (%d)\n", count);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
unw_step (&cursor);
|
unw_step (&cursor);
|
||||||
|
|
||||||
|
count = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
unw_get_reg (&cursor, UNW_REG_IP, &ip);
|
unw_get_reg (&cursor, UNW_REG_IP, &ip);
|
||||||
|
@ -111,6 +121,13 @@ sighandler (int signal)
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf ("ip = %lx <%s%s>\n", (long) ip, name, off);
|
printf ("ip = %lx <%s%s>\n", (long) ip, name, off);
|
||||||
++count;
|
++count;
|
||||||
|
|
||||||
|
if (count > 20)
|
||||||
|
{
|
||||||
|
panic ("Too many steps (%d)\n", count);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
while (unw_step (&cursor) > 0);
|
while (unw_step (&cursor) > 0);
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ struct itimerval interval =
|
||||||
|
|
||||||
int verbose;
|
int verbose;
|
||||||
int nerrors;
|
int nerrors;
|
||||||
|
static const int nerrors_max = 100;
|
||||||
int sigcount;
|
int sigcount;
|
||||||
|
|
||||||
#define panic(args...) \
|
#define panic(args...) \
|
||||||
|
@ -54,6 +55,7 @@ do_backtrace (int may_print, int get_proc_name)
|
||||||
unw_word_t ip, sp, off;
|
unw_word_t ip, sp, off;
|
||||||
unw_context_t uc;
|
unw_context_t uc;
|
||||||
int ret;
|
int ret;
|
||||||
|
int depth = 0;
|
||||||
|
|
||||||
unw_getcontext (&uc);
|
unw_getcontext (&uc);
|
||||||
if (unw_init_local (&cursor, &uc) < 0)
|
if (unw_init_local (&cursor, &uc) < 0)
|
||||||
|
@ -92,6 +94,11 @@ do_backtrace (int may_print, int get_proc_name)
|
||||||
panic ("FAILURE: unw_step() returned %d for ip=%lx\n",
|
panic ("FAILURE: unw_step() returned %d for ip=%lx\n",
|
||||||
ret, (long) ip);
|
ret, (long) ip);
|
||||||
}
|
}
|
||||||
|
if (depth++ > 100)
|
||||||
|
{
|
||||||
|
panic ("FAILURE: unw_step() looping over %d iterations\n", depth);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (ret > 0);
|
while (ret > 0);
|
||||||
}
|
}
|
||||||
|
@ -110,8 +117,10 @@ sighandler (int signal)
|
||||||
unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL);
|
unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL);
|
||||||
else if (sigcount == 200)
|
else if (sigcount == 200)
|
||||||
unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD);
|
unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD);
|
||||||
else if (sigcount == 300)
|
else if (sigcount == 300 || nerrors > nerrors_max)
|
||||||
{
|
{
|
||||||
|
if (nerrors > nerrors_max)
|
||||||
|
panic ("Too many errors (%d)\n", nerrors);
|
||||||
if (nerrors)
|
if (nerrors)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "FAILURE: detected %d errors\n", nerrors);
|
fprintf (stderr, "FAILURE: detected %d errors\n", nerrors);
|
||||||
|
@ -147,5 +156,10 @@ main (int argc, char **argv)
|
||||||
if (0 && verbose)
|
if (0 && verbose)
|
||||||
printf ("%s: starting backtrace\n", __FUNCTION__);
|
printf ("%s: starting backtrace\n", __FUNCTION__);
|
||||||
do_backtrace (0, (i++ % 100) == 0);
|
do_backtrace (0, (i++ % 100) == 0);
|
||||||
|
if (nerrors > nerrors_max)
|
||||||
|
{
|
||||||
|
panic ("Too many errors (%d)\n", nerrors);
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ main (int argc, char **argv)
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
int nerrors;
|
int nerrors;
|
||||||
|
static const int nerrors_max = 100;
|
||||||
int verbose;
|
int verbose;
|
||||||
int print_names = 1;
|
int print_names = 1;
|
||||||
|
|
||||||
|
@ -65,6 +66,8 @@ trace_mode = SYSCALL;
|
||||||
static unw_addr_space_t as;
|
static unw_addr_space_t as;
|
||||||
static struct UPT_info *ui;
|
static struct UPT_info *ui;
|
||||||
|
|
||||||
|
static int killed;
|
||||||
|
|
||||||
void
|
void
|
||||||
do_backtrace (pid_t target_pid)
|
do_backtrace (pid_t target_pid)
|
||||||
{
|
{
|
||||||
|
@ -99,7 +102,7 @@ do_backtrace (pid_t target_pid)
|
||||||
len = strlen (buf);
|
len = strlen (buf);
|
||||||
if (len >= sizeof (buf) - 32)
|
if (len >= sizeof (buf) - 32)
|
||||||
len = sizeof (buf) - 32;
|
len = sizeof (buf) - 32;
|
||||||
sprintf (buf + len, "+0x%lx", off);
|
sprintf (buf + len, "+0x%lx", (unsigned long) off);
|
||||||
}
|
}
|
||||||
printf ("%016lx %-32s (sp=%016lx)\n", (long) ip, buf, (long) sp);
|
printf ("%016lx %-32s (sp=%016lx)\n", (long) ip, buf, (long) sp);
|
||||||
}
|
}
|
||||||
|
@ -139,6 +142,11 @@ do_backtrace (pid_t target_pid)
|
||||||
(long) start_ip);
|
(long) start_ip);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (nerrors > nerrors_max)
|
||||||
|
{
|
||||||
|
panic ("Too many errors (%d)!\n", nerrors);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (ret > 0);
|
while (ret > 0);
|
||||||
|
|
||||||
|
@ -149,11 +157,16 @@ do_backtrace (pid_t target_pid)
|
||||||
printf ("================\n\n");
|
printf ("================\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static pid_t target_pid;
|
||||||
|
static void target_pid_kill (void)
|
||||||
|
{
|
||||||
|
kill (target_pid, SIGKILL);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
int status, pid, pending_sig, optind = 1, state = 1;
|
int status, pid, pending_sig, optind = 1, state = 1;
|
||||||
pid_t target_pid;
|
|
||||||
|
|
||||||
as = unw_create_addr_space (&_UPT_accessors, 0);
|
as = unw_create_addr_space (&_UPT_accessors, 0);
|
||||||
if (!as)
|
if (!as)
|
||||||
|
@ -199,10 +212,11 @@ main (int argc, char **argv)
|
||||||
execve (argv[optind], argv + optind, environ);
|
execve (argv[optind], argv + optind, environ);
|
||||||
_exit (-1);
|
_exit (-1);
|
||||||
}
|
}
|
||||||
|
atexit (target_pid_kill);
|
||||||
|
|
||||||
ui = _UPT_create (target_pid);
|
ui = _UPT_create (target_pid);
|
||||||
|
|
||||||
while (1)
|
while (nerrors <= nerrors_max)
|
||||||
{
|
{
|
||||||
pid = wait4 (-1, &status, 0, 0);
|
pid = wait4 (-1, &status, 0, 0);
|
||||||
if (pid == -1)
|
if (pid == -1)
|
||||||
|
@ -224,12 +238,16 @@ main (int argc, char **argv)
|
||||||
}
|
}
|
||||||
else if (WIFSIGNALED (status))
|
else if (WIFSIGNALED (status))
|
||||||
{
|
{
|
||||||
|
if (!killed)
|
||||||
panic ("child terminated by signal %d\n", WTERMSIG (status));
|
panic ("child terminated by signal %d\n", WTERMSIG (status));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pending_sig = WSTOPSIG (status);
|
pending_sig = WSTOPSIG (status);
|
||||||
|
/* Avoid deadlock: */
|
||||||
|
if (WSTOPSIG (status) == SIGKILL)
|
||||||
|
break;
|
||||||
if (trace_mode == TRIGGER)
|
if (trace_mode == TRIGGER)
|
||||||
{
|
{
|
||||||
if (WSTOPSIG (status) == SIGUSR1)
|
if (WSTOPSIG (status) == SIGUSR1)
|
||||||
|
@ -237,6 +255,17 @@ main (int argc, char **argv)
|
||||||
else if (WSTOPSIG (status) == SIGUSR2)
|
else if (WSTOPSIG (status) == SIGUSR2)
|
||||||
state = 1;
|
state = 1;
|
||||||
}
|
}
|
||||||
|
if (WSTOPSIG (status) != SIGUSR1 && WSTOPSIG (status) != SIGUSR2)
|
||||||
|
{
|
||||||
|
static int count = 0;
|
||||||
|
|
||||||
|
if (count++ > 100)
|
||||||
|
{
|
||||||
|
panic ("Too many child unexpected signals (now %d)\n",
|
||||||
|
WSTOPSIG (status));
|
||||||
|
killed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,6 +293,8 @@ main (int argc, char **argv)
|
||||||
ptrace (PTRACE_SINGLESTEP, target_pid, 0, pending_sig);
|
ptrace (PTRACE_SINGLESTEP, target_pid, 0, pending_sig);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (killed)
|
||||||
|
kill (target_pid, SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
_UPT_destroy (ui);
|
_UPT_destroy (ui);
|
||||||
|
|
Loading…
Add table
Reference in a new issue