From a72abd4e46eb6e92747412fb036d0fb8279350ac Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Wed, 16 May 2007 13:16:31 -0600 Subject: [PATCH] 2007-04-05 Jan Kratochvil * 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 * 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 * 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 * tests/test-ptrace.c (main): Check for too many unexpected child signals, such as the common `SIGSEGV'. --- tests/Gtest-dyn1.c | 23 ++++++++++++++++++++--- tests/test-async-sig.c | 16 +++++++++++++++- tests/test-ptrace.c | 39 +++++++++++++++++++++++++++++++++++---- 3 files changed, 70 insertions(+), 8 deletions(-) diff --git a/tests/Gtest-dyn1.c b/tests/Gtest-dyn1.c index 5e3f1a3f..2faa1f7a 100644 --- a/tests/Gtest-dyn1.c +++ b/tests/Gtest-dyn1.c @@ -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); diff --git a/tests/test-async-sig.c b/tests/test-async-sig.c index a114bff9..0aea21ca 100644 --- a/tests/test-async-sig.c +++ b/tests/test-async-sig.c @@ -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); + } } } diff --git a/tests/test-ptrace.c b/tests/test-ptrace.c index 2bbbee20..11fffee4 100644 --- a/tests/test-ptrace.c +++ b/tests/test-ptrace.c @@ -48,6 +48,7 @@ main (int argc, char **argv) #include 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);