[Lldb-commits] [PATCH] D134849: [LLDB][NativePDB] Fix struct layout when it has anonymous unions.

Zequan Wu via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Wed Sep 28 19:57:42 PDT 2022


zequanwu created this revision.
zequanwu added reviewers: labath, rnk.
Herald added a project: All.
zequanwu requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Previously, lldb mistook fields in anonymous union in a struct as the direct
field of the struct, which causes lldb crashes due to multiple fields sharing
the same offset in a struct. This patch fixes it.

MSVC generated pdb doesn't have the debug info entity representing a anonymous
union in a struct. It looks like the following:

  struct S {
  union {
    char c;
    int i;
  };
  };
  
  0x1004 | LF_FIELDLIST [size = 40]
           - LF_MEMBER [name = `c`, Type = 0x0070 (char), offset = 0, attrs = public]
           - LF_MEMBER [name = `i`, Type = 0x0074 (int), offset = 0, attrs = public]
  0x1005 | LF_STRUCTURE [size = 32] `S`
           unique name: `.?AUS@@`
           vtable: <no type>, base list: <no type>, field list: 0x1004

Clang generated pdb is similar, though due to the bug <https://github.com/llvm/llvm-project/issues/57999>,
it's not more useful than the debug info above. But that's not very relavent,
lldb should still be able to understand MSVC geneerated pdb.

  0x1003 | LF_UNION [size = 60] `S::<unnamed-tag>`
           unique name: `.?AT<unnamed-type-$S1>@S@@`
           field list: <no type>
           options: forward ref (= 0x1003) | has unique name | is nested, sizeof 0
  0x1004 | LF_FIELDLIST [size = 40]
           - LF_MEMBER [name = `c`, Type = 0x0070 (char), offset = 0, attrs = public]
           - LF_MEMBER [name = `i`, Type = 0x0074 (int), offset = 0, attrs = public]
           - LF_NESTTYPE [name = ``, parent = 0x1003]
  0x1005 | LF_STRUCTURE [size = 32] `S`
           unique name: `.?AUS@@`
           vtable: <no type>, base list: <no type>, field list: 0x1004
           options: contains nested class | has unique name, sizeof 4
  0x1006 | LF_FIELDLIST [size = 28]
           - LF_MEMBER [name = `c`, Type = 0x0070 (char), offset = 0, attrs = public]
           - LF_MEMBER [name = `i`, Type = 0x0074 (int), offset = 0, attrs = public]
  0x1007 | LF_UNION [size = 60] `S::<unnamed-tag>`
           unique name: `.?AT<unnamed-type-$S1>@S@@`
           field list: 0x1006
           options: has unique name | is nested | sealed, sizeof

This patch delays the FieldDecl creation when travesing LF_FIELDLIST so we know
if there are multiple fields are in the same offsets and are able to group them
into different anonymous unions based on offsets. Nested anonymous union will
be flatten into one anonymous union, because we simply don't have that info, but
they are equivalent in terms of union layout.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D134849

Files:
  lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
  lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
  lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
  lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
  lldb/test/Shell/SymbolFile/NativePDB/Inputs/class_layout.lldbinit
  lldb/test/Shell/SymbolFile/NativePDB/class_layout.cpp
  lldb/test/Shell/SymbolFile/NativePDB/global-classes.cpp
  lldb/test/Shell/SymbolFile/NativePDB/packed_class_layout.cpp
  lldb/test/Shell/SymbolFile/NativePDB/tag-types.cpp

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D134849.463750.patch
Type: text/x-patch
Size: 26180 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20220929/c9a4db83/attachment-0001.bin>


More information about the lldb-commits mailing list