https://bugs.kde.org/show_bug.cgi?id=443605

            Bug ID: 443605
           Summary: Don't call final_tidyup (__libc_freeres) on
                    FatalSignal
           Product: valgrind
           Version: unspecified
          Platform: Other
                OS: Linux
            Status: REPORTED
          Severity: normal
          Priority: NOR
         Component: general
          Assignee: jsew...@acm.org
          Reporter: m...@klomp.org
  Target Milestone: ---

When a program gets a fatal signal (one it doesn't handle) valgrind terminates
the program. Before termination it will try to call final_tidyup which tries to
run __libc_freeres and __gnu_cxx::__freeres to get rid of some memory glibc or
libstdc++ don't normally release.

But when the program got the fatal signal in a critical section inside glibc it
might leave the datastructures in a bad state and cause __libc_freeres to
crash.  This makes valgrind itself crash just before producing its own error
summary, making the valgrind run unusable.

A reproducer can found at https://bugzilla.redhat.com/show_bug.cgi?id=1952836
and https://bugzilla.redhat.com/show_bug.cgi?id=1225994#c7

This reproducer is really a worse case scenario with multiple threads racing to
get into the critical section that when interrupted will make __libc_freeres
unable to cleanup. But it seems a good policy in general. If a program is
terminated by a fatal signal instead of normal termination, it seems not having
some of the glibc/libstdc++ resource cleaned up is an expected thing.

The following patch implements this:

diff --git a/coregrind/m_main.c b/coregrind/m_main.c
index 56f9c6cbf..70b6c0549 100644
--- a/coregrind/m_main.c
+++ b/coregrind/m_main.c
@@ -2168,6 +2168,7 @@ void shutdown_actions_NORETURN( ThreadId tid,
             || tids_schedretcode == VgSrc_ExitProcess
              || tids_schedretcode == VgSrc_FatalSig );

+   /* Try to do final tidyup on "normal" exit, not on FatalSig.  */
    if (tids_schedretcode == VgSrc_ExitThread) {

       // We are the last surviving thread.  Right?
@@ -2185,7 +2186,7 @@ void shutdown_actions_NORETURN( ThreadId tid,
       vg_assert(VG_(is_running_thread)(tid));
       vg_assert(VG_(count_living_threads)() == 1);

-   } else {
+   } else if (tids_schedretcode == VgSrc_ExitProcess) {

       // We may not be the last surviving thread.  However, we
       // want to shut down the entire process.  We hold the lock

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to