(Please keep me on CC, I am not subscribed)

In working on another patch for DW_AT_comp_dir behaviour, I tried to write a
test for that other patch. This test did not work as expected - DW_AT_comp_dir
was not even generated in the resulting output! But this had nothing to do with
my patch so I dug a bit deeper.

It turns out that GCC does not emit DW_AT_comp_dir if the source path given is
an absolute path, and the file being compiled contains a typedef to a compiler
builtin (sorry, I don't know the terminology here very well). This typedef
exists in the vast majority of cases in the real world via standard library
includes, so from the outside, the behaviour of GCC "looks like" it emits
DW_AT_comp_dir in all/most cases.

>From looking at the source code dwarf2out.c, Richard Biener determined that the
current code is written to "intend to" not emit DW_AT_comp_dir if to path is
absolute, regardless of the typedef. It is possible to "fix" this bug by a
1-line change, to conform to the way currently "intended" by GCC code. However,
I think a much better fix is a 22-line deletion of code from dwarf2out.c, to
instead emit DW_AT_comp_dir in all cases.

The original aim of not emitting DW_AT_comp_dir seems to be to avoid emitting
redundant information. However, this information is *not* redundant! The DWARF2
spec says:

"A DW_AT_comp_dir attribute whose value is a null-terminated string containing
the current working directory of the compilation command that produced this
compilation unit in whatever form makes sense for the host system."

Conceptually, the working directory is independent from an input file, so it
would *not* be redundant to emit it in the general case. In future versions of
DWARF, other information might be added (such as relative -I flags, etc) that
are dependent on knowing the working directory. The logic of "don't emit
DW_AT_comp_dir if DW_AT_name is absolute" would then break. In other words, the
choice to avoid emitting DW_AT_comp_dir is a brittle and premature optimisation
that loses information in the general case. Therefore, it is better to emit it
in all circumstances, in case the reader needs to know what the working
directory was at compile-time.

*Sometimes*, *parts* of it might be redundant yes - and rewriting DW_AT_name to
be relative to this, would remove the redundancy. Doing this is compatible with
the above points, and I could amend the patch to do this - although I suggest
it's not worth the effort, unless there is a function in GCC code that already
does this.

Some more minor advantages are:

- We delete 21 lines, this reduces complexity in the already-complex code.
  We can also get rid of the Darwin-specific workaround described here:
  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53453 (Not currently part of my
  patch, but I can add this in.)

- The GCC test suite compiles tests via their absolute paths, and many many
  other buildsystems do this too. This was in fact my original problem - I was
  trying to test something involving DW_AT_comp_dir, but GCC does not emit this
  in the testsuite! Rather than saying "this is a bug, everyone else should
  spend effort fixing this", it is better to fix it in one place, i.e. the
  source of where it is (not) generated.

Thanks for your time,


GPG: ed25519/56034877E1F87C35
GPG: rsa4096/1318EFAC5FBBDBCE
Index: gcc-7-20161009/gcc/dwarf2out.c
--- gcc-7-20161009.orig/gcc/dwarf2out.c
+++ gcc-7-20161009/gcc/dwarf2out.c
@@ -21994,7 +21994,7 @@ gen_compile_unit_die (const char *filena
       add_name_attribute (die, filename);
       /* Don't add cwd for <built-in>.  */
-      if (!IS_ABSOLUTE_PATH (filename) && filename[0] != '<')
+      if (filename[0] != '<')
 	add_comp_dir_attribute (die);
@@ -26332,20 +26332,6 @@ prune_unused_types (void)
     prune_unmark_dies (ctnode->root_die);
-/* Set the parameter to true if there are any relative pathnames in
-   the file table.  */
-file_table_relative_p (dwarf_file_data **slot, bool *p)
-  struct dwarf_file_data *d = *slot;
-  if (!IS_ABSOLUTE_PATH (d->filename))
-    {
-      *p = true;
-      return 0;
-    }
-  return 1;
 /* Helpers to manipulate hash table of comdat type units.  */
 struct comdat_type_hasher : nofree_ptr_hash <comdat_type_node>
@@ -28152,15 +28138,7 @@ dwarf2out_early_finish (const char *file
   /* Add the name for the main input file now.  We delayed this from
      dwarf2out_init to avoid complications with PCH.  */
   add_name_attribute (comp_unit_die (), remap_debug_filename (filename));
-  if (!IS_ABSOLUTE_PATH (filename) || targetm.force_at_comp_dir)
-    add_comp_dir_attribute (comp_unit_die ());
-  else if (get_AT (comp_unit_die (), DW_AT_comp_dir) == NULL)
-    {
-      bool p = false;
-      file_table->traverse<bool *, file_table_relative_p> (&p);
-      if (p)
-	add_comp_dir_attribute (comp_unit_die ());
-    }
+  add_comp_dir_attribute (comp_unit_die ());
   /* With LTO early dwarf was really finished at compile-time, so make
      sure to adjust the phase after annotating the LTRANS CU DIE.  */
Index: gcc-7-20161009/gcc/testsuite/gcc.dg/debug/dwarf2/pr77985.c
--- /dev/null
+++ gcc-7-20161009/gcc/testsuite/gcc.dg/debug/dwarf2/pr77985.c
@@ -0,0 +1,9 @@
+/* DW_AT_comp_dir is emitted even if the file is compiled via an absolute path,
+   as is the case in the gcc testsuite. */
+/* { dg-do compile } */
+/* { dg-options "-g -dA" } */
+/* { dg-final { scan-assembler-dem "DW_AT_comp_dir:" } } */
+void func (void)

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to