]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Merged r9653..r9655 (fixed terminal signal handling in Darwin) from DARWIN
authorNicholas Nethercote <njn@valgrind.org>
Tue, 28 Apr 2009 01:55:01 +0000 (01:55 +0000)
committerNicholas Nethercote <njn@valgrind.org>
Tue, 28 Apr 2009 01:55:01 +0000 (01:55 +0000)
branch.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9656

coregrind/m_signals.c
memcheck/tests/Makefile.am
memcheck/tests/addressable.c
memcheck/tests/addressable.stderr.exp
memcheck/tests/addressable.stderr.exp2 [deleted file]
memcheck/tests/addressable.vgtest
memcheck/tests/filter_addressable [new file with mode: 0755]

index e5fe8457532c7e2e27ca0df34ab53c7c3656ee65..31dc5e444de3ef56a6ddeeed2ff5f2bc7e95b392 100644 (file)
@@ -1137,6 +1137,24 @@ void VG_(kill_self)(Int sigNo)
    VG_(sigprocmask)(VKI_SIG_SETMASK, &origmask, NULL);
 }
 
+// The si_code describes where the signal came from.  Some come from the
+// kernel, eg.: seg faults, illegal opcodes.  Some come from the user, eg.:
+// from kill() (SI_USER), or timer_settime() (SI_TIMER), or an async I/O
+// request (SI_ASYNCIO).  There's lots of implementation-defined leeway in
+// POSIX, but the user vs. kernal distinction is what we want here.
+static Bool is_signal_from_kernel(int si_code)
+{
+#if defined(VGO_linux) || defined(VGO_aix5)
+   // On Linux, SI_USER is zero, negative values are from the user, positive
+   // values are from the kernel.  There are SI_FROMUSER and SI_FROMKERNEL
+   // macros but we don't use them here because other platforms don't have
+   // them.
+   return ( si_code > VKI_SI_USER ? True : False );
+#else
+#  error Unknown OS
+#endif
+}
+
 /* 
    Perform the default action of a signal.  If the signal is fatal, it
    marks all threads as needing to exit, but it doesn't actually kill
@@ -1208,15 +1226,17 @@ static void default_action(const vki_siginfo_t *info, ThreadId tid)
         core = False;
    }
 
-   if ( (VG_(clo_verbosity) > 1 || (could_core && info->si_code > VKI_SI_USER)) 
-        && !VG_(clo_xml) ) {
+   if ( (VG_(clo_verbosity) > 1 ||
+         (could_core && is_signal_from_kernel(info->si_code))
+        ) &&
+        !VG_(clo_xml) ) {
       VG_(message)(Vg_UserMsg, "");
       VG_(message)(Vg_UserMsg, 
                    "Process terminating with default action of signal %d (%s)%s", 
                   sigNo, signame(sigNo), core ? ": dumping core" : "");
 
       /* Be helpful - decode some more details about this fault */
-      if (info->si_code > VKI_SI_USER) {
+      if (is_signal_from_kernel(info->si_code)) {
         const Char *event = NULL;
         Bool haveaddr = True;
 
@@ -1299,7 +1319,7 @@ static void default_action(const vki_siginfo_t *info, ThreadId tid)
          VG_(pp_ExeContext)( ec );
       }
       if (sigNo == VKI_SIGSEGV 
-          && info && info->si_code > VKI_SI_USER 
+          && info && is_signal_from_kernel(info->si_code)
           && info->si_code == VKI_SEGV_MAPERR) {
          VG_(message)(Vg_UserMsg, " If you believe this happened as a "
                                   "result of a stack overflow in your");
@@ -1744,7 +1764,24 @@ void sync_signalhandler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext *u
    info->si_code = (Short)info->si_code;
 #endif
 
-   if (info->si_code <= VKI_SI_USER) {
+   /* // debug code:
+   if (0) {
+      VG_(printf)("info->si_signo  %d\n", info->si_signo);
+      VG_(printf)("info->si_errno  %d\n", info->si_errno);
+      VG_(printf)("info->si_code   %d\n", info->si_code);
+      VG_(printf)("info->si_pid    %d\n", info->si_pid);
+      VG_(printf)("info->si_uid    %d\n", info->si_uid);
+      VG_(printf)("info->si_status %d\n", info->si_status);
+      VG_(printf)("info->si_addr   %p\n", info->si_addr);
+   }
+   */
+
+   /* Figure out if the signal is being sent from outside the process.
+      (Why do we care?)  If the signal is from the user rather than the
+      kernel,, then treat it more like an async signal than a sync signal --
+      that is, merely queue it for later delivery. */
+
+   if (!is_signal_from_kernel(info->si_code)) {
       /* If some user-process sent us one of these signals (ie,
         they're not the result of a faulting instruction), then treat
         it as an async signal.  This is tricky because we could get
@@ -1812,7 +1849,7 @@ void sync_signalhandler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext *u
         queue_signal(0, info); /* shared pending */
 
       return;
-   } 
+   } /* if (!is_signal_from_kernel(info->si_code)) */
 
    if (VG_(clo_trace_signals)) {
       VG_(message)(Vg_DebugMsg, "signal %d arrived ... si_code=%d, "
index 2962f8f1efc534d1f0509e95f312bc2003ce2c70..72a432ee3cacd4103ad8851b398add638f2f2f26 100644 (file)
@@ -23,9 +23,11 @@ endif
 
 DIST_SUBDIRS = x86 amd64 linux x86-linux .
 
-noinst_SCRIPTS = filter_allocs \
-                filter_stderr filter_xml \
-                filter_varinfo3
+noinst_SCRIPTS = \
+       filter_addressable \
+       filter_allocs \
+       filter_stderr filter_xml \
+       filter_varinfo3
 
 EXTRA_DIST = $(noinst_SCRIPTS) \
        addressable.stderr.exp addressable.stdout.exp addressable.vgtest \
index f845ef3d099d7984454f4be37139667b808ebfd2..bb6da4fce2d7632f3ea07eedd8c087b534314651 100644 (file)
@@ -93,12 +93,12 @@ static void test5()
 
 static struct test {
        void (*test)(void);
-       int sig;
+       int faults;
 } tests[] = {
        { test1, 0 },
-       { test2, SIGSEGV },
+       { test2, 1 },
        { test3, 0 },
-       { test4, SIGSEGV },
+       { test4, 1 },
        { test5, 0 },
 };
 static const int n_tests = sizeof(tests)/sizeof(*tests);
@@ -140,18 +140,19 @@ int main()
                        if (WIFSIGNALED(status)) {
                                assert(WTERMSIG(status) != 0);
 
-                               if (WTERMSIG(status) == tests[i].sig)
+                               if (1 == tests[i].faults &&
+                                   (WTERMSIG(status) == SIGSEGV ||
+                                    WTERMSIG(status) == SIGBUS))
                                        printf("PASS\n");
                                else
                                        printf("died with unexpected signal %d\n", 
                                               WTERMSIG(status));
                        } else if (WIFEXITED(status)) {
                                if (WEXITSTATUS(status) == 0) {
-                                       if (tests[i].sig == 0)
+                                       if (tests[i].faults == 0)
                                                printf("PASS\n");
                                        else
-                                               printf("exited without expected signal %d\n",
-                                                      tests[i].sig);
+                                               printf("exited without expected SIGSEGV or SIGBUS signal\n");
                                } else
                                        printf("exited with unexpected status %d\n",
                                               WEXITSTATUS(status));
index ef8265698b9c3d4fa0baa60594600c627daa077f..ad76e96c7e78060d1e93e52e1c4c915fea4038cb 100644 (file)
@@ -15,8 +15,8 @@ Invalid write of size 1
    by 0x........: main (addressable.c:125)
  Address 0x........ is not stack'd, malloc'd or (recently) free'd
 
-Process terminating with default action of signal 11 (SIGSEGV)
Access not within mapped region at address 0x........
+Process terminating with default action of signal N (SIGSEGV or SIGBUS)
Bad memory (SIGSEGV or SIGBUS) at address 0x........
    at 0x........: test2 (addressable.c:51)
    by 0x........: main (addressable.c:125)
  If you believe this happened as a result of a stack overflow in your
@@ -36,8 +36,8 @@ malloc/free: ... allocs, ... frees, ... bytes allocated.
 For a detailed leak analysis,  rerun with: --leak-check=yes
 For counts of detected errors, rerun with: -v
 
-Process terminating with default action of signal 11 (SIGSEGV)
- Bad permissions for mapped region at address 0x........
+Process terminating with default action of signal N (SIGSEGV or SIGBUS)
+ Bad memory (SIGSEGV or SIGBUS) at address 0x........
    at 0x........: test4 (addressable.c:74)
    by 0x........: main (addressable.c:125)
 
diff --git a/memcheck/tests/addressable.stderr.exp2 b/memcheck/tests/addressable.stderr.exp2
deleted file mode 100644 (file)
index 4b73958..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-
-
-ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
-malloc/free: in use at exit: ... bytes in ... blocks.
-malloc/free: ... allocs, ... frees, ... bytes allocated.
-For a detailed leak analysis,  rerun with: --leak-check=yes
-For counts of detected errors, rerun with: -v
-Unaddressable byte(s) found during client check request
-   at 0x........: test2 (addressable.c:48)
-   by 0x........: main (addressable.c:125)
- Address 0x........ is not stack'd, malloc'd or (recently) free'd
-
-Invalid write of size 1
-   at 0x........: test2 (addressable.c:51)
-   by 0x........: main (addressable.c:125)
- Address 0x........ is not stack'd, malloc'd or (recently) free'd
-
-Process terminating with default action of signal 11 (SIGSEGV)
- Access not within mapped region at address 0x........
-   at 0x........: test2 (addressable.c:51)
-   by 0x........: main (addressable.c:125)
-
-ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
-malloc/free: in use at exit: ... bytes in ... blocks.
-malloc/free: ... allocs, ... frees, ... bytes allocated.
-For a detailed leak analysis,  rerun with: --leak-check=yes
-For counts of detected errors, rerun with: -v
-
-ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
-malloc/free: in use at exit: ... bytes in ... blocks.
-malloc/free: ... allocs, ... frees, ... bytes allocated.
-For a detailed leak analysis,  rerun with: --leak-check=yes
-For counts of detected errors, rerun with: -v
-
-Process terminating with default action of signal 11 (SIGSEGV)
- Bad permissions for mapped region at address 0x........
-   at 0x........: test4 (addressable.c:74)
-   by 0x........: main (addressable.c:125)
-
-ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
-malloc/free: in use at exit: ... bytes in ... blocks.
-malloc/free: ... allocs, ... frees, ... bytes allocated.
-For a detailed leak analysis,  rerun with: --leak-check=yes
-For counts of detected errors, rerun with: -v
-Uninitialised byte(s) found during client check request
-   at 0x........: test5 (addressable.c:85)
-   by 0x........: main (addressable.c:125)
- Address 0x........ is 10 bytes inside a block of size 20480 client-defined
-   at 0x........: test5 (addressable.c:82)
-   by 0x........: main (addressable.c:125)
-
-Uninitialised byte(s) found during client check request
-   at 0x........: test5 (addressable.c:91)
-   by 0x........: main (addressable.c:125)
- Address 0x........ is 20 bytes inside a block of size 20480 client-defined
-   at 0x........: test5 (addressable.c:82)
-   by 0x........: main (addressable.c:125)
-
-ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
-malloc/free: in use at exit: ... bytes in ... blocks.
-malloc/free: ... allocs, ... frees, ... bytes allocated.
-For a detailed leak analysis,  rerun with: --leak-check=yes
-For counts of detected errors, rerun with: -v
-Use --track-origins=yes to see where uninitialised values come from
-
-ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
-malloc/free: in use at exit: ... bytes in ... blocks.
-malloc/free: ... allocs, ... frees, ... bytes allocated.
-For a detailed leak analysis,  rerun with: --leak-check=yes
-For counts of detected errors, rerun with: -v
index c6c032ba54104a39aebf7913b55baf2fae414a68..c91bff5fa5a6bc99a9a31d14a84b40807cf7e581 100644 (file)
@@ -1,2 +1,2 @@
 prog: addressable
-stderr_filter: filter_allocs
+stderr_filter: filter_addressable
diff --git a/memcheck/tests/filter_addressable b/memcheck/tests/filter_addressable
new file mode 100755 (executable)
index 0000000..f89cf85
--- /dev/null
@@ -0,0 +1,7 @@
+#! /bin/sh
+
+./filter_allocs |
+perl -p -e 's/(default action of signal) [0-9]+ \(SIG(SEGV|BUS)\)/$1 N \(SIGSEGV or SIGBUS\)/' |
+perl -p -e 's/(Bad permissions for mapped region|Access not within mapped region|Non-existent physical address) at address 0x/Bad memory (SIGSEGV or SIGBUS) at address 0x/'
+
+