1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-22 23:47:39 +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:
Jan Kratochvil 2007-05-16 13:16:31 -06:00 committed by David Mosberger-Tang
parent 7923ae31a0
commit a72abd4e46
3 changed files with 70 additions and 8 deletions

View file

@ -87,7 +87,7 @@ sighandler (int signal)
char name[128], off[32];
unw_word_t ip, offset;
unw_context_t uc;
int count = 0;
int count;
if (verbose)
printf ("caught signal %d\n", signal);
@ -95,11 +95,21 @@ sighandler (int signal)
unw_getcontext (&uc);
unw_init_local (&cursor, &uc);
count = 0;
while (!unw_is_signal_frame (&cursor))
{
if (unw_step (&cursor) < 0)
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);
count = 0;
do
{
unw_get_reg (&cursor, UNW_REG_IP, &ip);
@ -111,6 +121,13 @@ sighandler (int signal)
if (verbose)
printf ("ip = %lx <%s%s>\n", (long) ip, name, off);
++count;
if (count > 20)
{
panic ("Too many steps (%d)\n", count);
break;
}
}
while (unw_step (&cursor) > 0);

View file

@ -41,6 +41,7 @@ struct itimerval interval =
int verbose;
int nerrors;
static const int nerrors_max = 100;
int sigcount;
#define panic(args...) \
@ -54,6 +55,7 @@ do_backtrace (int may_print, int get_proc_name)
unw_word_t ip, sp, off;
unw_context_t uc;
int ret;
int depth = 0;
unw_getcontext (&uc);
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",
ret, (long) ip);
}
if (depth++ > 100)
{
panic ("FAILURE: unw_step() looping over %d iterations\n", depth);
break;
}
}
while (ret > 0);
}
@ -110,8 +117,10 @@ sighandler (int signal)
unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL);
else if (sigcount == 200)
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)
{
fprintf (stderr, "FAILURE: detected %d errors\n", nerrors);
@ -147,5 +156,10 @@ main (int argc, char **argv)
if (0 && verbose)
printf ("%s: starting backtrace\n", __FUNCTION__);
do_backtrace (0, (i++ % 100) == 0);
if (nerrors > nerrors_max)
{
panic ("Too many errors (%d)\n", nerrors);
exit (-1);
}
}
}

View file

@ -48,6 +48,7 @@ main (int argc, char **argv)
#include <sys/wait.h>
int nerrors;
static const int nerrors_max = 100;
int verbose;
int print_names = 1;
@ -65,6 +66,8 @@ trace_mode = SYSCALL;
static unw_addr_space_t as;
static struct UPT_info *ui;
static int killed;
void
do_backtrace (pid_t target_pid)
{
@ -99,7 +102,7 @@ do_backtrace (pid_t target_pid)
len = strlen (buf);
if (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);
}
@ -139,6 +142,11 @@ do_backtrace (pid_t target_pid)
(long) start_ip);
break;
}
if (nerrors > nerrors_max)
{
panic ("Too many errors (%d)!\n", nerrors);
break;
}
}
while (ret > 0);
@ -149,11 +157,16 @@ do_backtrace (pid_t target_pid)
printf ("================\n\n");
}
static pid_t target_pid;
static void target_pid_kill (void)
{
kill (target_pid, SIGKILL);
}
int
main (int argc, char **argv)
{
int status, pid, pending_sig, optind = 1, state = 1;
pid_t target_pid;
as = unw_create_addr_space (&_UPT_accessors, 0);
if (!as)
@ -199,10 +212,11 @@ main (int argc, char **argv)
execve (argv[optind], argv + optind, environ);
_exit (-1);
}
atexit (target_pid_kill);
ui = _UPT_create (target_pid);
while (1)
while (nerrors <= nerrors_max)
{
pid = wait4 (-1, &status, 0, 0);
if (pid == -1)
@ -224,12 +238,16 @@ main (int argc, char **argv)
}
else if (WIFSIGNALED (status))
{
if (!killed)
panic ("child terminated by signal %d\n", WTERMSIG (status));
break;
}
else
{
pending_sig = WSTOPSIG (status);
/* Avoid deadlock: */
if (WSTOPSIG (status) == SIGKILL)
break;
if (trace_mode == TRIGGER)
{
if (WSTOPSIG (status) == SIGUSR1)
@ -237,6 +255,17 @@ main (int argc, char **argv)
else if (WSTOPSIG (status) == SIGUSR2)
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);
break;
}
if (killed)
kill (target_pid, SIGKILL);
}
_UPT_destroy (ui);