]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Callgrind: fix interactive control after fork()
authorJosef Weidendorfer <Josef.Weidendorfer@gmx.de>
Wed, 20 Sep 2006 21:29:39 +0000 (21:29 +0000)
committerJosef Weidendorfer <Josef.Weidendorfer@gmx.de>
Wed, 20 Sep 2006 21:29:39 +0000 (21:29 +0000)
This fixes bug 134316: when an program in callgrind does
a fork, callgrind_control does show both now, and they
can be controlled separately.

However, missing in this patch is zeroing of cost centers
directly after the clone syscall in the child.

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

callgrind/command.c
callgrind/dump.c
callgrind/global.h
callgrind/main.c

index 10ad909c2443f1e8b2a410b272d6e09f38ac39a4..edbd6d5c80e53d49de64610e9f170eac8451e3a5 100644 (file)
@@ -48,20 +48,35 @@ static Char* current_result_file = 0;
 static Char* info_file = 0;
 static Char* dump_base = 0;
 
-static Bool command_inited = False;
+static Int thisPID = 0;
 
-void CLG_(init_command)(Char* dir, Char* dumps)
+/**
+ * Setup for interactive control of a callgrind run
+ */
+static void setup_control(void)
 {
-  Int fd = -1, size;
+  Int fd, size;
   SysRes res;
+  Char* dir, *dump_filename;
+
+  CLG_ASSERT(thisPID != 0);
+
+  fd = -1;
+  dir = CLG_(get_base_directory)();
+  dump_base = CLG_(get_dump_file_base)();
 
-  dump_base = dumps;
+  /* base name of dump files with PID ending */
+  size = VG_(strlen)(dump_base) + 10;
+  dump_filename = (char*) CLG_MALLOC(size);
+  CLG_ASSERT(dump_filename != 0);
+  VG_(sprintf)(dump_filename, "%s.%d", dump_base, thisPID);
 
+  /* name of command file */
   size = VG_(strlen)(dir) + VG_(strlen)(DEFAULT_COMMANDNAME) +10;
   command_file = (char*) CLG_MALLOC(size);
   CLG_ASSERT(command_file != 0);
   VG_(sprintf)(command_file, "%s/%s.%d",
-              dir, DEFAULT_COMMANDNAME, VG_(getpid)());
+              dir, DEFAULT_COMMANDNAME, thisPID);
 
   /* This is for compatibility with the "Force Now" Button of current
    * KCachegrind releases, as it doesn't use ".pid" to distinguish
@@ -76,7 +91,7 @@ void CLG_(init_command)(Char* dir, Char* dumps)
   result_file = (char*) CLG_MALLOC(size);
   CLG_ASSERT(result_file != 0);
   VG_(sprintf)(result_file, "%s/%s.%d",
-              dir, DEFAULT_RESULTNAME, VG_(getpid)());
+              dir, DEFAULT_RESULTNAME, thisPID);
 
   /* If we get a command from a command file without .pid, use
    * a result file without .pid suffix
@@ -88,9 +103,10 @@ void CLG_(init_command)(Char* dir, Char* dumps)
 
   info_file = (char*) CLG_MALLOC(VG_(strlen)(DEFAULT_INFONAME) + 10);
   CLG_ASSERT(info_file != 0);
-  VG_(sprintf)(info_file, "%s.%d", DEFAULT_INFONAME, VG_(getpid)());
+  VG_(sprintf)(info_file, "%s.%d", DEFAULT_INFONAME, thisPID);
 
-  CLG_DEBUG(1, "  dump file base: '%s'\n", dump_base);
+  CLG_DEBUG(1, "Setup for interactive control (PID: %d):\n", thisPID);
+  CLG_DEBUG(1, "  dump file base: '%s'\n", dump_filename);
   CLG_DEBUG(1, "  command file:   '%s'\n", command_file);
   CLG_DEBUG(1, "  result file:    '%s'\n", result_file);
   CLG_DEBUG(1, "  info file:      '%s'\n", info_file);
@@ -128,7 +144,7 @@ void CLG_(init_command)(Char* dir, Char* dumps)
     VG_(sprintf)(buf, "base: %s\n", dir);
     VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
     
-    VG_(sprintf)(buf, "dumps: %s\n", dump_base);
+    VG_(sprintf)(buf, "dumps: %s\n", dump_filename);
     VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
     
     VG_(sprintf)(buf, "control: %s\n", command_file);
@@ -149,8 +165,12 @@ void CLG_(init_command)(Char* dir, Char* dumps)
     VG_(write)(fd, "\n", 1);
     VG_(close)(fd);
   }
+}
 
-  command_inited = True;
+void CLG_(init_command)()
+{
+  thisPID = VG_(getpid)();
+  setup_control();
 }
 
 void CLG_(finish_command)()
@@ -355,14 +375,31 @@ void CLG_(check_command)()
     Char *cmdPos = 0, *cmdNextLine = 0;
     Int fd, bytesRead = 0, do_kill = 0;
     SysRes res;
+    Int currentPID;
+    static Int check_counter = 0;
 
-    if (!command_inited) return;
+    /* Check for PID change, i.e. whether we run as child after a fork.
+     * If yes, we setup interactive control for the new process
+     */
+    currentPID = VG_(getpid)();
+    if (thisPID != currentPID) {
+       thisPID = currentPID;
+       setup_control();
+    }
 
-    /* toggle between 2 command files, with/without ".pid" postfix */
-    current_command_file = (current_command_file == command_file2) ? 
-                           command_file : command_file2;
-    current_result_file  = (current_command_file == command_file2) ?
-                           result_file2 : result_file;    
+    /* Toggle between 2 command files, with/without ".pid" postfix
+     * (needed for compatibility with KCachegrind, which wants to trigger
+     *  a dump by writing into a command file without the ".pid" postfix)
+     */
+    check_counter++;
+    if (check_counter % 2) {
+       current_command_file = command_file;
+       current_result_file  = result_file;
+    }
+    else {
+       current_command_file = command_file2;
+       current_result_file  = result_file2;
+    }
     
     res = VG_(open)(current_command_file, VKI_O_RDONLY,0);
     if (!res.isError) {
index ae730c7c9cacec2e20862607fd47b6aff7cfe4f0..f9bc6521c3c8bd866b70b04018e8d0b53c9ce71d 100644 (file)
 #include <pub_tool_threadstate.h>
 #include <pub_tool_libcfile.h>
 
-/*------------------------------------------------------------*/
-/*--- Support for signal handlers and multi-threading      ---*/
-/*------------------------------------------------------------*/
 
 /* Dump Part Counter */
 static Int out_counter = 0;
 
 static Char* dump_file_base = 0;
 static Char* base_directory = 0;
+static Bool dumps_initialized = False;
 
 /* Command */
 static Char cmdbuf[BUF_LEN];
@@ -66,7 +64,14 @@ Int CLG_(get_dump_counter)(void)
 
 Char* CLG_(get_dump_file_base)()
 {
-  return dump_file_base;
+    CLG_ASSERT(dumps_initialized);
+    return dump_file_base;
+}
+
+Char* CLG_(get_base_directory)()
+{
+    CLG_ASSERT(dumps_initialized);
+    return base_directory;
 }
 
 /*------------------------------------------------------------*/
@@ -1264,6 +1269,7 @@ static int new_dumpfile(Char buf[BUF_LEN], int tid, Char* trigger)
     FullCost sum = 0;
     SysRes res;
 
+    CLG_ASSERT(dumps_initialized);
     CLG_ASSERT(filename != 0);
 
     if (!CLG_(clo).combine_dumps) {
@@ -1641,10 +1647,20 @@ void init_cmdbuf(void)
   cmdbuf[size] = 0;
 }
 
-void CLG_(init_files)(Char** dir, Char** file)
+/*
+ * Set up file names for dump output: base_directory, dump_file_base
+ * The final filename of a dump is constructed at dump time from
+ * the PID, thread ID and dump counter.
+ *
+ * These always will contain a full absolute path.
+ * If no prefix is given (via option "--base=<prefix>"), the current
+ * working directory at program start is used, otherwise <prefix> can
+ * be relative to cwd or absolute.
+ */
+void CLG_(init_dumps)()
 {
-  Int size;
-  SysRes res;
+   Int size;
+   SysRes res;
 
    if (!CLG_(clo).filename_base)
      CLG_(clo).filename_base = DEFAULT_DUMPNAME;
@@ -1709,8 +1725,7 @@ void CLG_(init_files)(Char** dir, Char** file)
     }
     if (!res.isError) VG_(close)( (Int)res.val );
 
-    *dir  = base_directory;
-    *file = filename;
-
     init_cmdbuf();
+
+    dumps_initialized = True;
 }
index 0079b4d3a0a75c1d7fb94399f4d719cbe43cc5ad..335de14618e7927c35350aeb4115bc86e1cdba64 100644 (file)
@@ -675,7 +675,7 @@ Int CLG_(get_dump_counter)(void);
 void CLG_(fini)(Int exitcode);
 
 /* from command.c */
-void CLG_(init_command)(Char* dir, Char* dumps);
+void CLG_(init_command)(void);
 void CLG_(check_command)(void);
 void CLG_(finish_command)(void);
 
@@ -761,9 +761,9 @@ void CLG_(run_post_signal_on_call_stack_bottom)(void);
 
 /* from dump.c */
 extern FullCost CLG_(total_cost);
-void CLG_(init_files)(Char** dir, Char** file);
+void CLG_(init_dumps)(void);
 Char* CLG_(get_dump_file_base)(void);
-
+Char* CLG_(get_base_directory)(void);
 
 /*------------------------------------------------------------*/
 /*--- Exported global variables                            ---*/
index aa88a9df3c2347a27c11eaff649eeda05d46863e..d0c0f4052d7b908d2874f1969f60b57dfdea20d3 100644 (file)
@@ -1028,8 +1028,6 @@ void CLG_(fini)(Int exitcode)
 static
 void CLG_(post_clo_init)(void)
 {
-   Char *dir = 0, *fname = 0;
-
    VG_(clo_vex_control).iropt_unroll_thresh = 0;
    VG_(clo_vex_control).guest_chase_thresh = 0;
 
@@ -1042,8 +1040,8 @@ void CLG_(post_clo_init)(void)
        CLG_(clo).dump_line = True;
    }
 
-   CLG_(init_files)(&dir,&fname);
-   CLG_(init_command)(dir,fname);
+   CLG_(init_dumps)();
+   CLG_(init_command)();
 
    (*CLG_(cachesim).post_clo_init)();