[LLVMdev] [llvm-dev] DwarfDebug craziness

Nick Lewycky nicholas at mxc.ca
Sun Dec 18 23:13:39 PST 2011


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
>




More information about the llvm-dev mailing list