(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, Ximin -- GPG: ed25519/56034877E1F87C35 GPG: rsa4096/1318EFAC5FBBDBCE https://github.com/infinity0/pubkeys.git
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. */ -int -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) +{ +}
signature.asc
Description: OpenPGP digital signature