[LLVMdev] [llvm-dev] DwarfDebug craziness
Josh Matthews
josh at joshmatthews.net
Sun Dec 18 23:40:44 PST 2011
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
>>
>
More information about the llvm-dev
mailing list