This is an archive of the discontinued LLVM Phabricator instance.

[DebugInfo][CodeView] Include namespace into emitted globals
ClosedPublic

Authored by aganea on Apr 28 2020, 11:20 AM.

Details

Summary

Before this patch, global variables didn't have their namespace prepended in the Codeview debug symbol stream. This prevented Visual Studio from displaying them in the debugger (they appeared as 'unspecified error')

Diff Detail

Event Timeline

aganea created this revision.Apr 28 2020, 11:20 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 28 2020, 11:21 AM
aganea updated this revision to Diff 260708.Apr 28 2020, 11:24 AM

Simplify.

aganea updated this revision to Diff 260729.Apr 28 2020, 12:25 PM

Fix tests.

aganea retitled this revision from [DebugInfo][COFF] Include namespace into emitted globals to [DebugInfo][CodeView] Include namespace into emitted globals.Apr 30 2020, 6:19 AM
aganea added a reviewer: amccarth.
rnk accepted this revision.Apr 30 2020, 7:13 AM
rnk added a subscriber: akhuang.

lgtm

llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
3146

Looks like @akhuang got this right recently for S_CONSTANT, but we've had the bug with global names since forever. :(

llvm/test/DebugInfo/COFF/globals.ll
145

I'm not sure why we check the relocations here in the first place. They use offsets, so they tend to be fragile. I think we ought to remove them from this test. We have enough coverage from the ASM check lines above. As long as we have confidence that .secrel and .secidx directives work and are tested elsewhere, this seems redundant.

This revision is now accepted and ready to land.Apr 30 2020, 7:13 AM
aganea updated this revision to Diff 261322.Apr 30 2020, 12:50 PM
aganea marked 3 inline comments as done.

Fix local thread_local which shouldn't generate a scoped name in S_LTHREAD32.

llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
3146

I've updated the code above a bit. There was an edge case with S_LTHREAD32 which needed to emit a unscoped name. Could you please take a quick look again?

I'm noting by the way that extern thread_local int A; does not generate a debug symbol :( I haven't checked why yet.

rnk added inline comments.Apr 30 2020, 1:25 PM
llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
3116

I think this isn't quite right. Consider:

$ cat t.cpp
namespace foo {
thread_local int global_tls;
int global_int() { return ++global_tls; }
static thread_local int static_tls;
int static_int() { return ++static_tls; }
int func_int() {
  thread_local int func_tls;
  return ++func_tls;
}
int func_static_int() {
  static int func_static;
  return ++func_static;
}
}

$ cl  -c t.cpp  -Z7 && llvm-pdbutil dump -symbols t.obj  | grep 'THREA\|DATA'
Microsoft (R) C/C++ Optimizing Compiler Version 19.25.28612 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

t.cpp
       0 | S_LTHREAD32 [size = 23] `func_tls`
       0 | S_LDATA32 [size = 26] `func_static`
       0 | S_GTHREAD32 [size = 30] `foo::global_tls`
       0 | S_LTHREAD32 [size = 30] `foo::static_tls`

It's function local TLS that shouldn't receive a fully qualified name. Let's handle that separately. Those are probably less common. I'm OK committing the previous patchset and handling function local globals separately.

To fix function local globals (thread local or otherwise), we have to walk up the DIGV scope and see if any of them is a subprogram. We have some existing logic for this for UDTs (typedefs).

amccarth accepted this revision.Apr 30 2020, 2:40 PM

LGTM>

Apologies for the delay. I thought I had already responded to this one.

aganea updated this revision to Diff 261522.May 1 2020, 12:51 PM
aganea marked an inline comment as done.

Fix static thread_local, ie. S_LTHREAD32.

aganea requested review of this revision.May 1 2020, 12:56 PM

Thanks @amccarth ! Would you mind taking a second look please? The stream now matches MSVC behavior.

llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
3116

I've updated to only handle namespaces. I'll write a follow-up patch to fix the subprogram prefix after landing this.

I've also noted that statics inside a class don't seem to generate the right qualifier either in the debug stream:

$ cat a.cpp
struct Data {
  inline static thread_local int DataStaticTLS = 5;
  inline static int DataGlobalStatic = 7;
};
int bar() {
  foo::Data D;
  return D.DataStaticTLS + D.DataGlobalStatic;
}
$ cl /Z7 /GS- /c a.cpp /Od /std:c++17 && link /DEBUG /INCREMENTAL:NO a.obj /NODEFAULTLIB /FORCE /ENTRY:bar /SUBSYSTEM:console && llvm-pdbutil.exe dump --all a.pdb | grep S_G.*Data
     132 | S_GTHREAD32 [size = 36] `Data::DataStaticTLS`
     168 | S_GDATA32 [size = 40] `Data::DataGlobalStatic`

With clang-cl (this patch applied):

132 | S_GTHREAD32 [size = 28] `DataStaticTLS`
160 | S_GDATA32 [size = 32] `DataGlobalStatic`
amccarth accepted this revision.May 4 2020, 8:22 AM
This revision is now accepted and ready to land.May 4 2020, 8:22 AM
aganea marked an inline comment as done.May 4 2020, 10:08 AM

Thank you!

This revision was automatically updated to reflect the committed changes.