>From DwarfDebug.cpp:>/// GetOrCreateSourceID - Look up the source id with the given directory and >/// source file names. If none currently exists, create a new id and insert it >/// in the SourceIds map. This can update DirectoryNames and SourceFileNames >/// maps as well. >unsigned DwarfDebug::GetOrCreateSourceID(StringRef FileName, > StringRef DirName) { > // If FE did not provide a file name, then assume stdin. > if (FileName.empty()) > return GetOrCreateSourceID("<stdin>", StringRef()); > > // TODO: this might not belong here. See if we can factor this better. > if (DirName == CompilationDir) > DirName = "";The last snippet weirds me out and breaks Rust debug information generation. Specifically, when creating a new compile unit, we see this:>CompileUnit *DwarfDebug::constructCompileUnit(const MDNode *N) { > DICompileUnit DIUnit(N); > StringRef FN = DIUnit.getFilename(); > CompilationDir = DIUnit.getDirectory(); > unsigned ID = GetOrCreateSourceID(FN, CompilationDir);Note how CompilationDir is passed to GetOrCreateSourceID as DirName? That means that the map of compilation units is created entirely based on file names excluding the path, so two compilation units that happen to share a name generate identical source IDs and then attempt to generate duplicate symbols for labels. For a temporary workaround locally I've deleted the check in GetOrCreateSourceID, but I have no idea if that has other negative consequences. Can someone who understands what's going on here comment? Cheers, Josh
Josh Matthews wrote:>> From DwarfDebug.cpp: > >> /// GetOrCreateSourceID - Look up the source id with the given directory and >> /// source file names. If none currently exists, create a new id and insert it >> /// in the SourceIds map. This can update DirectoryNames and SourceFileNames >> /// maps as well. >> unsigned DwarfDebug::GetOrCreateSourceID(StringRef FileName, >> StringRef DirName) { >> // If FE did not provide a file name, then assume stdin. >> if (FileName.empty()) >> return GetOrCreateSourceID("<stdin>", StringRef()); >> >> // TODO: this might not belong here. See if we can factor this better. >> if (DirName == CompilationDir) >> DirName = ""; > > The last snippet weirds me out and breaks Rust debug information > generation. Specifically, when creating a new compile unit, we see > this:In DWARF, if the directory index is zero then it's assumed to be the contents of AT_compilation_dir. This implements that optimization.>> CompileUnit *DwarfDebug::constructCompileUnit(const MDNode *N) { >> DICompileUnit DIUnit(N); >> StringRef FN = DIUnit.getFilename(); >> CompilationDir = DIUnit.getDirectory(); >> unsigned ID = GetOrCreateSourceID(FN, CompilationDir); > > Note how CompilationDir is passed to GetOrCreateSourceID as DirName? > That means that the map of compilation units is created entirely based > on file names excluding the path, so two compilation units that happen > to share a name generate identical source IDs and then attempt to > generate duplicate symbols for labels.The file name does not exclude the path: $ cat a/a.c int a(void) { return 0; } $ clang a/a.c -g -S -o - -flto | grep DW_TAG_compile_unit !0 = metadata !{i32 720913, i32 0, i32 12, metadata !"a/a.c", metadata !"/home/nicholas", metadata !"clang version 3.1 (trunk 146849)", i1 true, i1 false, metadata !"", i32 0, metadata !1, metadata !1, metadata !3, metadata !1} ; [ DW_TAG_compile_unit ] Note that the filename is "a/a.c", not "a.c". The directory is also correct, as the file is indeed in /home/nicholas/a/a.c . For a temporary workaround> locally I've deleted the check in GetOrCreateSourceID, but I have no > idea if that has other negative consequences. Can someone who > understands what's going on here comment?How is this breaking rust? Nick> > Cheers, > Josh > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
Oh, I see. I was operating under the assumption that the descriptions from the docs> metadata, ;; Source file name > metadata, ;; Source file directory (includes trailing slash)were equivalent to basename(file) and dirname(file) respectively. Thanks for clearing this up. Cheers, Josh On 19 December 2011 02:13, Nick Lewycky <nicholas at mxc.ca> wrote:> Josh Matthews wrote: >>> >>> From DwarfDebug.cpp: >> >> >>> /// GetOrCreateSourceID - Look up the source id with the given directory >>> and >>> /// source file names. If none currently exists, create a new id and >>> insert it >>> /// in the SourceIds map. This can update DirectoryNames and >>> SourceFileNames >>> /// maps as well. >>> unsigned DwarfDebug::GetOrCreateSourceID(StringRef FileName, >>> StringRef DirName) { >>> // If FE did not provide a file name, then assume stdin. >>> if (FileName.empty()) >>> return GetOrCreateSourceID("<stdin>", StringRef()); >>> >>> // TODO: this might not belong here. See if we can factor this better. >>> if (DirName == CompilationDir) >>> DirName = ""; >> >> >> The last snippet weirds me out and breaks Rust debug information >> generation. Specifically, when creating a new compile unit, we see >> this: > > > In DWARF, if the directory index is zero then it's assumed to be the > contents of AT_compilation_dir. This implements that optimization. > > >>> CompileUnit *DwarfDebug::constructCompileUnit(const MDNode *N) { >>> DICompileUnit DIUnit(N); >>> StringRef FN = DIUnit.getFilename(); >>> CompilationDir = DIUnit.getDirectory(); >>> unsigned ID = GetOrCreateSourceID(FN, CompilationDir); >> >> >> Note how CompilationDir is passed to GetOrCreateSourceID as DirName? >> That means that the map of compilation units is created entirely based >> on file names excluding the path, so two compilation units that happen >> to share a name generate identical source IDs and then attempt to >> generate duplicate symbols for labels. > > > The file name does not exclude the path: > > $ cat a/a.c > int a(void) { return 0; } > $ clang a/a.c -g -S -o - -flto | grep DW_TAG_compile_unit > !0 = metadata !{i32 720913, i32 0, i32 12, metadata !"a/a.c", metadata > !"/home/nicholas", metadata !"clang version 3.1 (trunk 146849)", i1 true, i1 > false, metadata !"", i32 0, metadata !1, metadata !1, metadata !3, metadata > !1} ; [ DW_TAG_compile_unit ] > > Note that the filename is "a/a.c", not "a.c". The directory is also correct, > as the file is indeed in /home/nicholas/a/a.c . > > > For a temporary workaround >> >> locally I've deleted the check in GetOrCreateSourceID, but I have no >> idea if that has other negative consequences. Can someone who >> understands what's going on here comment? > > > How is this breaking rust? > > Nick > >> >> Cheers, >> Josh >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> >
Apparently Analagous Threads
- [LLVMdev] DwarfDebug craziness
- [LLVMdev] Pulling line number/file/path information from DbgStopPointInst instructions
- [LLVMdev] Pulling line number/file/path information from DbgStopPointInst instructions
- [LLVMdev] [patch] DwarfDebug problem with line section
- [LLVMdev] [patch] DwarfDebug problem with line section