[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[committed] Add --devel-save-temps



Hi,

The temporary files used in multifile mode are of interest when debugging
multifile issues, but they are removed after dwz has run.

Add a developer-only option --devel-save-temps to make these files available:
...
$ dwz --devel-save-temps -m 3 1 2
$ ls -1 dwz.*
dwz.debug_abbrev
dwz.debug_info
dwz.debug_line
dwz.debug_macro
dwz.debug_str
...

These files can then be added to a dummy elf file using a new convenience
script contrib/gen-dwz-debug-all.sh, which then can be inspected using
f.i. readelf:
...
$ ./contrib/gen-dwz-debug-all.sh
$ readelf -wi dwz.debug_all
...

Committed to trunk.

Thanks,
- Tom

Add --devel-save-temps

2019-10-21  Tom de Vries  <tdevries@suse.de>

	* dwz.c (save_temps): New variable.
	(dwz_options): Add --devel-save-temps entry.
	(make_temp_file): New function, factored out of ...
	(main): ... here.
	(make_temp_file): Handle save_temps.
	* contrib/gen-dwz-debug-all.sh: New script.
	* testsuite/dwz.tests/save-temps.sh: New test.

---
 contrib/gen-dwz-debug-all.sh      | 28 +++++++++++++
 dwz.c                             | 87 +++++++++++++++++++++++++++++----------
 testsuite/dwz.tests/save-temps.sh | 18 ++++++++
 3 files changed, 112 insertions(+), 21 deletions(-)

diff --git a/contrib/gen-dwz-debug-all.sh b/contrib/gen-dwz-debug-all.sh
new file mode 100755
index 0000000..943062c
--- /dev/null
+++ b/contrib/gen-dwz-debug-all.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+outputfile=dwz.debug_all
+
+echo "
+  int
+  main (void)
+  {
+    return 0;
+  }
+" \
+    | gcc -x c - -c -o $outputfile
+
+sections="
+  debug_abbrev
+  debug_info
+  debug_line
+  debug_macro
+  debug_str
+"
+
+for section in $sections; do
+    file=dwz.$section
+
+    objcopy \
+	--add-section .$section=$file \
+       $outputfile
+done
diff --git a/dwz.c b/dwz.c
index a34c354..e762fb7 100644
--- a/dwz.c
+++ b/dwz.c
@@ -12358,6 +12358,66 @@ alt_clear_dups (dw_die_ref die)
     }
 }
 
+static int save_temps = 0;
+
+/* Create a temporary file using NAME.  Return the corresponding file
+   descriptor if successful, otherwise return -1.  */
+static int
+make_temp_file (const char *name)
+{
+  const char *tmpdir = "/tmp/";
+  const char *template_suffix = ".XXXXXX";
+  int fd;
+  size_t buf_len, offset, name_len;
+  char *buf;
+
+  if (save_temps)
+    {
+      FILE *f = fopen (name, "w+");
+      if (f == NULL)
+	fd = -1;
+      else
+	fd = fileno (f);
+      return fd;
+    }
+
+  name_len = strlen (name);
+  buf_len = (strlen (tmpdir)
+	     + name_len
+	     + strlen (template_suffix)
+	     + 1);
+  if (buf_len < name_len)
+    return -1;
+  buf = (char *)malloc (buf_len);
+  if (buf == NULL)
+    return -1;
+  offset = 0;
+
+  strncpy (&buf[offset], tmpdir, buf_len - offset);
+  offset += strlen (tmpdir);
+
+  strncpy (&buf[offset], name, buf_len - offset);
+  offset += name_len;
+
+  strncpy (&buf[offset], template_suffix, buf_len - offset);
+  offset += strlen (template_suffix);
+
+  assert (offset == buf_len - 1);
+  assert (buf[offset] == '\0');
+
+  fd = mkstemp (buf);
+  if (fd == -1)
+    goto done;
+
+  /* Unlink the filename, such that the file is disposed of once the file
+     descriptor is closed.  */
+  unlink (buf);
+
+ done:
+  free (buf);
+  return fd;
+}
+
 /* Options for getopt_long.  */
 static struct option dwz_options[] =
 {
@@ -12375,6 +12435,7 @@ static struct option dwz_options[] =
   { "devel-trace",	 no_argument,	    &tracing, 1 },
   { "devel-ignore-size", no_argument,	    &ignore_size, 1 },
   { "devel-ignore-locus",no_argument,	    &ignore_locus, 1 },
+  { "devel-save-temps",  no_argument,	    &save_temps, 1 },
 #endif
   { NULL,		 no_argument,	    0, 0 }
 };
@@ -12511,27 +12572,11 @@ main (int argc, char *argv[])
 	error (1, 0, "-o option not allowed for multiple files");
       if (multifile)
 	{
-	  char buf[sizeof "/tmp/dwz.debug_abbrev.XXXXXX"];
-	  strcpy (buf, "/tmp/dwz.debug_info.XXXXXX");
-	  multi_info_fd = mkstemp (buf);
-	  if (multi_info_fd != -1)
-	    unlink (buf);
-	  strcpy (buf, "/tmp/dwz.debug_abbrev.XXXXXX");
-	  multi_abbrev_fd = mkstemp (buf);
-	  if (multi_abbrev_fd != -1)
-	    unlink (buf);
-	  strcpy (buf, "/tmp/dwz.debug_line.XXXXXX");
-	  multi_line_fd = mkstemp (buf);
-	  if (multi_line_fd != -1)
-	    unlink (buf);
-	  strcpy (buf, "/tmp/dwz.debug_str.XXXXXX");
-	  multi_str_fd = mkstemp (buf);
-	  if (multi_str_fd != -1)
-	    unlink (buf);
-	  strcpy (buf, "/tmp/dwz.debug_macro.XXXXXX");
-	  multi_macro_fd = mkstemp (buf);
-	  if (multi_macro_fd != -1)
-	    unlink (buf);
+	  multi_info_fd = make_temp_file ("dwz.debug_info");
+	  multi_abbrev_fd = make_temp_file ("dwz.debug_abbrev");
+	  multi_line_fd = make_temp_file ("dwz.debug_line");
+	  multi_str_fd = make_temp_file ("dwz.debug_str");
+	  multi_macro_fd = make_temp_file ("dwz.debug_macro");
 	  if (multi_info_fd == -1
 	      || multi_abbrev_fd == -1
 	      || multi_line_fd == -1
diff --git a/testsuite/dwz.tests/save-temps.sh b/testsuite/dwz.tests/save-temps.sh
new file mode 100644
index 0000000..bf83980
--- /dev/null
+++ b/testsuite/dwz.tests/save-temps.sh
@@ -0,0 +1,18 @@
+cp $execs/hello 1
+cp $execs/hello 2
+
+$execs/dwz-for-test --devel-save-temps -m 3 1 2
+
+files="
+  dwz.debug_abbrev
+  dwz.debug_info
+  dwz.debug_line
+  dwz.debug_macro
+  dwz.debug_str
+"
+
+for f in $files; do
+    [ -f $f ]
+done
+
+rm -f 1 2 3 $files