mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-11-22 15:47:37 +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];
|
||||
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 (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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
panic ("child terminated by signal %d\n", WTERMSIG (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);
|
||||
|
|
Loading…
Reference in a new issue