]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Get rid of pub_core_main.h, so that m_main is not imported by anyone,
authorJulian Seward <jseward@acm.org>
Wed, 28 Sep 2005 10:47:38 +0000 (10:47 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 28 Sep 2005 10:47:38 +0000 (10:47 +0000)
and so is not part of a module cycle.  This requires a moderately
grotty hack of passing a continuation-function pointer in a global
variable.

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

coregrind/Makefile.am
coregrind/m_main.c
coregrind/m_syswrap/syswrap-amd64-linux.c
coregrind/m_syswrap/syswrap-generic.c
coregrind/m_syswrap/syswrap-main.c
coregrind/m_syswrap/syswrap-ppc32-linux.c
coregrind/m_syswrap/syswrap-x86-linux.c
coregrind/pub_core_main.h [deleted file]
coregrind/pub_core_syswrap.h

index 2296abefd6db0da3f8c73cdd31edfe95f3e0a019..bae2988f1de25dae232d0eb62ddf31ac853ae2af 100644 (file)
@@ -48,7 +48,6 @@ noinst_HEADERS = \
        pub_core_libcproc.h     \
        pub_core_libcsignal.h   \
        pub_core_machine.h      \
-       pub_core_main.h         \
        pub_core_mallocfree.h   \
        pub_core_options.h      \
        pub_core_oset.h         \
index a0886059f939ffbde9429b607a7510f8c5b2afe2..50a50fa047356c12ccd8351c95013f60c7c9ffb8 100644 (file)
@@ -44,7 +44,6 @@
 #include "pub_core_libcsignal.h"
 #include "pub_core_syscall.h"       // VG_(strerror)
 #include "pub_core_machine.h"
-#include "pub_core_main.h"
 #include "pub_core_mallocfree.h"
 #include "pub_core_options.h"
 #include "pub_core_profile.h"
@@ -1823,6 +1822,16 @@ void show_BB_profile ( BBProfEntry tops[], UInt n_tops, ULong score_total )
 
 static Addr sp_at_startup = 0;
 
+/* --- Forwards decls to do with shutdown --- */
+
+static void final_tidyup(ThreadId tid); 
+
+/* Do everything which needs doing when the last thread exits */
+static 
+void shutdown_actions_NORETURN( ThreadId tid, 
+                                VgSchedReturnCode tids_schedretcode );
+
+/* --- end of Forwards decls to do with shutdown --- */
 
 
 /* TODO: GIVE THIS A PROPER HOME
@@ -1860,8 +1869,6 @@ static Addr* get_seg_starts ( /*OUT*/Int* n_acquired )
 
 
 
-
-
 Int main(Int argc, HChar **argv, HChar **envp)
 {
    HChar*  toolname          = "memcheck";    // default to Memcheck
@@ -2480,67 +2487,33 @@ Int main(Int argc, HChar **argv, HChar **envp)
    }
 
    VG_(debugLog)(1, "main", "Running thread 1\n");
+
    /* As a result of the following call, the last thread standing
-      eventually winds up running VG_(shutdown_actions_NORETURN) just
-      below. */
+      eventually winds up running shutdown_actions_NORETURN
+      just below.  Unfortunately, simply exporting said function
+      causes m_main to be part of a module cycle, which is pretty
+      nonsensical.  So instead of doing that, the address of said
+      function is stored in a global variable 'owned' by m_syswrap,
+      and it uses that function pointer to get back here when it needs
+      to. */
+
+   /* Set continuation address. */
+   VG_(address_of_m_main_shutdown_actions_NORETURN)
+      = & shutdown_actions_NORETURN;
+
+   /* Run the first thread, eventually ending up at the continuation
+      address. */
    VG_(main_thread_wrapper_NORETURN)(1);
 
    /*NOTREACHED*/
    vg_assert(0);
 }
 
+/* Do everything which needs doing when the last thread exits. */
 
-/* Final clean-up before terminating the process.  
-   Clean up the client by calling __libc_freeres() (if requested) 
-   This is Linux-specific?
-*/
-static void final_tidyup(ThreadId tid)
-{
-   Addr __libc_freeres_wrapper;
-
-   vg_assert(VG_(is_running_thread)(tid));
-   
-   if ( !VG_(needs).libc_freeres ||
-        !VG_(clo_run_libc_freeres) ||
-        0 == (__libc_freeres_wrapper = VG_(get_libc_freeres_wrapper)()) )
-      return;                  /* can't/won't do it */
-
-   if (VG_(clo_verbosity) > 2  ||
-       VG_(clo_trace_syscalls) ||
-       VG_(clo_trace_sched))
-      VG_(message)(Vg_DebugMsg, 
-                  "Caught __NR_exit; running __libc_freeres()");
-      
-   /* point thread context to point to libc_freeres_wrapper */
-   VG_(set_IP)(tid, __libc_freeres_wrapper);
-   // XXX should we use a special stack?
-
-   /* Block all blockable signals by copying the real block state into
-      the thread's block state*/
-   VG_(sigprocmask)(VKI_SIG_BLOCK, NULL, &VG_(threads)[tid].sig_mask);
-   VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
-
-   /* and restore handlers to default */
-   VG_(set_default_handler)(VKI_SIGSEGV);
-   VG_(set_default_handler)(VKI_SIGBUS);
-   VG_(set_default_handler)(VKI_SIGILL);
-   VG_(set_default_handler)(VKI_SIGFPE);
-
-   // We were exiting, so assert that...
-   vg_assert(VG_(is_exiting)(tid));
-   // ...but now we're not again
-   VG_(threads)[tid].exitreason = VgSrc_None;
-
-   // run until client thread exits - ideally with LIBC_FREERES_DONE,
-   // but exit/exitgroup/signal will do
-   VG_(scheduler)(tid);
-
-   vg_assert(VG_(is_exiting)(tid));
-}
-
-/* Do everything which needs doing when the last thread exits */
-void VG_(shutdown_actions_NORETURN) ( ThreadId tid, 
-                                      VgSchedReturnCode tids_schedretcode )
+static 
+void shutdown_actions_NORETURN( ThreadId tid, 
+                                VgSchedReturnCode tids_schedretcode )
 {
    VG_(debugLog)(1, "main", "entering VG_(shutdown_actions_NORETURN)\n");
 
@@ -2646,6 +2619,56 @@ void VG_(shutdown_actions_NORETURN) ( ThreadId tid,
    }
 }
 
+/* -------------------- */
+
+/* Final clean-up before terminating the process.  
+   Clean up the client by calling __libc_freeres() (if requested) 
+   This is Linux-specific?
+*/
+static void final_tidyup(ThreadId tid)
+{
+   Addr __libc_freeres_wrapper;
+
+   vg_assert(VG_(is_running_thread)(tid));
+   
+   if ( !VG_(needs).libc_freeres ||
+        !VG_(clo_run_libc_freeres) ||
+        0 == (__libc_freeres_wrapper = VG_(get_libc_freeres_wrapper)()) )
+      return;                  /* can't/won't do it */
+
+   if (VG_(clo_verbosity) > 2  ||
+       VG_(clo_trace_syscalls) ||
+       VG_(clo_trace_sched))
+      VG_(message)(Vg_DebugMsg, 
+                  "Caught __NR_exit; running __libc_freeres()");
+      
+   /* point thread context to point to libc_freeres_wrapper */
+   VG_(set_IP)(tid, __libc_freeres_wrapper);
+   // XXX should we use a special stack?
+
+   /* Block all blockable signals by copying the real block state into
+      the thread's block state*/
+   VG_(sigprocmask)(VKI_SIG_BLOCK, NULL, &VG_(threads)[tid].sig_mask);
+   VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
+
+   /* and restore handlers to default */
+   VG_(set_default_handler)(VKI_SIGSEGV);
+   VG_(set_default_handler)(VKI_SIGBUS);
+   VG_(set_default_handler)(VKI_SIGILL);
+   VG_(set_default_handler)(VKI_SIGFPE);
+
+   // We were exiting, so assert that...
+   vg_assert(VG_(is_exiting)(tid));
+   // ...but now we're not again
+   VG_(threads)[tid].exitreason = VgSrc_None;
+
+   // run until client thread exits - ideally with LIBC_FREERES_DONE,
+   // but exit/exitgroup/signal will do
+   VG_(scheduler)(tid);
+
+   vg_assert(VG_(is_exiting)(tid));
+}
+
 
 /*====================================================================*/
 /*=== Getting to main() alive                                      ===*/
index 6eafac3b2a7b0e0ffc1ca6e9f208a80d6064a3f9..309cdcbb05698acbcf9c1dcf7fc09c9d9aa380ee 100644 (file)
@@ -38,7 +38,6 @@
 #include "pub_core_libcprint.h"
 #include "pub_core_libcproc.h"
 #include "pub_core_libcsignal.h"
-#include "pub_core_main.h"
 #include "pub_core_scheduler.h"
 #include "pub_core_sigframe.h"
 #include "pub_core_signals.h"
@@ -133,8 +132,9 @@ static void run_a_thread_NORETURN ( Word tidW )
                           (ULong)tidW);
 
       /* We are the last one standing.  Keep hold of the lock and
-         carry on to show final tool results, then exit the entire system. */
-      VG_(shutdown_actions_NORETURN)(tid, src);
+         carry on to show final tool results, then exit the entire system. 
+         Use the continuation pointer set at startup in m_main. */
+      ( * VG_(address_of_m_main_shutdown_actions_NORETURN) ) (tid, src);
 
    } else {
 
index eac7239561e26462442246a6f3b9cb26d40115fe..0816e50163417f8d627afa39d1fd8f42cc3b7120 100644 (file)
@@ -42,7 +42,6 @@
 #include "pub_core_libcprint.h"
 #include "pub_core_libcproc.h"
 #include "pub_core_libcsignal.h"
-#include "pub_core_main.h"
 #include "pub_core_mallocfree.h"
 #include "pub_core_options.h"
 #include "pub_core_scheduler.h"
index 3bf1efcd5ff5d470885c1a7ce16e935621692640..821164ed87db419024a46b773c58db5646ad2203 100644 (file)
@@ -1153,6 +1153,20 @@ VG_(fixup_guest_state_after_syscall_interrupted)( ThreadId tid,
 }
 
 
+/* ---------------------------------------------------------------------
+   A place to store the where-to-call-when-really-done pointer
+   ------------------------------------------------------------------ */
+
+// When the final thread is done, where shall I call to shutdown the
+// system cleanly?  Is set once at startup (in m_main) and never
+// changes after that.  Is basically a pointer to the exit
+// continuation.  This is all just a nasty hack to avoid calling
+// directly from m_syswrap to m_main at exit, since that would cause
+// m_main to become part of a module cycle, which is silly.
+void (* VG_(address_of_m_main_shutdown_actions_NORETURN) )
+       (ThreadId,VgSchedReturnCode)
+   = NULL;
+
 /*--------------------------------------------------------------------*/
 /*--- end                                                          ---*/
 /*--------------------------------------------------------------------*/
index 648fb02f524df1cfec1f3584dd784306912516ae..0bac456af9839459dd1e872ad9c5ca75d3a5389c 100644 (file)
@@ -37,7 +37,6 @@
 #include "pub_core_libcprint.h"
 #include "pub_core_libcproc.h"
 #include "pub_core_libcsignal.h"
-#include "pub_core_main.h"          // For VG_(shutdown_actions_NORETURN)()
 #include "pub_core_options.h"
 #include "pub_core_scheduler.h"
 #include "pub_core_sigframe.h"      // For VG_(sigframe_destroy)()
@@ -158,8 +157,9 @@ static void run_a_thread_NORETURN ( Word tidW )
                           (ULong)tidW);
 
       /* We are the last one standing.  Keep hold of the lock and
-         carry on to show final tool results, then exit the entire system. */
-      VG_(shutdown_actions_NORETURN)(tid, src);
+         carry on to show final tool results, then exit the entire system. 
+         Use the continuation pointer set at startup in m_main. */
+      ( * VG_(address_of_m_main_shutdown_actions_NORETURN) ) (tid, src);
 
    } else {
       VG_(debugLog)(1, "syswrap-ppc32-linux", 
index 778f9b73848dd74fa190c2348e86542bb3b73b49..6f39f47b640719f538efd83d2b0df4746e0524c9 100644 (file)
@@ -43,7 +43,6 @@
 #include "pub_core_libcprint.h"
 #include "pub_core_libcproc.h"
 #include "pub_core_libcsignal.h"
-#include "pub_core_main.h"          // For VG_(shutdown_actions_NORETURN)()
 #include "pub_core_mallocfree.h"
 #include "pub_core_options.h"
 #include "pub_core_scheduler.h"
@@ -140,8 +139,9 @@ static void run_a_thread_NORETURN ( Word tidW )
                           (ULong)tidW);
 
       /* We are the last one standing.  Keep hold of the lock and
-         carry on to show final tool results, then exit the entire system. */
-      VG_(shutdown_actions_NORETURN)(tid, src);
+         carry on to show final tool results, then exit the entire system. 
+         Use the continuation pointer set at startup in m_main. */
+      ( * VG_(address_of_m_main_shutdown_actions_NORETURN) ) (tid, src);
 
    } else {
 
diff --git a/coregrind/pub_core_main.h b/coregrind/pub_core_main.h
deleted file mode 100644 (file)
index c8bbec6..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-
-/*--------------------------------------------------------------------*/
-/*--- The main module.                             pub_core_main.h ---*/
-/*--------------------------------------------------------------------*/
-
-/*
-   This file is part of Valgrind, a dynamic binary instrumentation
-   framework.
-
-   Copyright (C) 2000-2005 Julian Seward
-      jseward@acm.org
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307, USA.
-
-   The GNU General Public License is contained in the file COPYING.
-*/
-
-#ifndef __PUB_CORE_MAIN_H
-#define __PUB_CORE_MAIN_H
-
-//--------------------------------------------------------------------
-// PURPOSE: This module is the main module, ie. the one holding main().
-// It arguably shouldn't export anything to other modules, since it depends
-// on almost every other module!  But currently it exports quite a few
-// things.
-//--------------------------------------------------------------------
-
-// Do everything which needs doing before the process finally ends,
-// like printing reports, etc
-extern void VG_(shutdown_actions_NORETURN) (
-               ThreadId tid, 
-               VgSchedReturnCode tids_schedretcode 
-            );
-
-#endif   // __PUB_CORE_MAIN_H
-
-/*--------------------------------------------------------------------*/
-/*--- end                                                          ---*/
-/*--------------------------------------------------------------------*/
index 2c03321ff4f01be9f6babe9709ded5ea4d940e06..0cedba1ac3bc76f49a234d62c2d414800fb9fd1f 100644 (file)
@@ -66,6 +66,15 @@ extern void VG_(cleanup_thread) ( ThreadArchState* );
 extern void VG_(init_preopened_fds) ( void );
 extern void VG_(show_open_fds) ( void );
 
+// When the final thread is done, where shall I call to shutdown the
+// system cleanly?  Is set once at startup (in m_main) and never
+// changes after that.  Is basically a pointer to the exit
+// continuation.  This is all just a nasty hack to avoid calling
+// directly from m_syswrap to m_main at exit, since that would cause
+// m_main to become part of a module cycle, which is silly.
+extern void (* VG_(address_of_m_main_shutdown_actions_NORETURN) )
+            (ThreadId,VgSchedReturnCode);
+
 #endif   // __PUB_CORE_SYSWRAP_H
 
 /*--------------------------------------------------------------------*/