Skip to content

Commit aaae5f8

Browse files
author
Siva Chandra
committed
[DWARFASTParserClang] Start with member offset of 0 for members of union types.
Summary: GCC does not emit DW_AT_data_member_location for members of a union. Starting with a 0 value for member locations helps is reading union types in such cases. Reviewers: clayborg Subscribers: ldrumm, lldb-commits Differential Revision: http://reviews.llvm.org/D18008 llvm-svn: 263085
1 parent 7776377 commit aaae5f8

File tree

4 files changed

+70
-1
lines changed

4 files changed

+70
-1
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
LEVEL = ../../../make
2+
3+
C_SOURCES := main.c
4+
5+
include $(LEVEL)/Makefile.rules
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import lldb
2+
from lldbsuite.test.lldbtest import *
3+
import lldbsuite.test.lldbutil as lldbutil
4+
5+
class TestUnionMembers(TestBase):
6+
7+
mydir = TestBase.compute_mydir(__file__)
8+
9+
def test_union_members(self):
10+
self._load_exe()
11+
12+
# Set breakpoints
13+
bp = self.target.BreakpointCreateBySourceRegex("Break here", self.src_file_spec)
14+
self.assertTrue(bp.IsValid() and bp.GetNumLocations() >= 1, VALID_BREAKPOINT)
15+
16+
# Launch the process
17+
self.process = self.target.LaunchSimple(None, None, self.get_process_working_directory())
18+
self.assertTrue(self.process.IsValid(), PROCESS_IS_VALID)
19+
self.assertTrue(self.process.GetState() == lldb.eStateStopped, PROCESS_STOPPED)
20+
21+
thread = lldbutil.get_stopped_thread(self.process, lldb.eStopReasonBreakpoint)
22+
self.assertTrue(thread.IsValid())
23+
frame = thread.GetSelectedFrame()
24+
self.assertTrue(frame.IsValid())
25+
26+
val = frame.EvaluateExpression("u");
27+
self.assertTrue(val.IsValid())
28+
val = frame.EvaluateExpression("u.s");
29+
self.assertTrue(val.IsValid())
30+
self.assertEqual(val.GetNumChildren(), 2)
31+
32+
def _load_exe(self):
33+
self.build()
34+
35+
cwd = os.getcwd()
36+
37+
src_file = os.path.join(cwd, "main.c")
38+
self.src_file_spec = lldb.SBFileSpec(src_file)
39+
self.assertTrue(self.src_file_spec.IsValid(), "breakpoint file")
40+
41+
# Get the path of the executable
42+
exe_path = os.path.join(cwd, 'a.out')
43+
44+
# Load the executable
45+
self.target = self.dbg.CreateTarget(exe_path)
46+
self.assertTrue(self.target.IsValid(), VALID_TARGET)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include <stdint.h>
2+
3+
union S
4+
{
5+
int32_t n; // occupies 4 bytes
6+
uint16_t s[2]; // occupies 4 bytes
7+
uint8_t c; // occupies 1 byte
8+
}; // the whole union occupies 4 bytes
9+
10+
int main()
11+
{
12+
union S u;
13+
14+
u.s[0] = 1234;
15+
u.s[1] = 4321;
16+
17+
return 0; // Break here
18+
}

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2673,7 +2673,7 @@ DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
26732673
bool is_artificial = false;
26742674
DWARFFormValue encoding_form;
26752675
AccessType accessibility = eAccessNone;
2676-
uint32_t member_byte_offset = UINT32_MAX;
2676+
uint32_t member_byte_offset = (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX;
26772677
size_t byte_size = 0;
26782678
size_t bit_offset = 0;
26792679
size_t bit_size = 0;

0 commit comments

Comments
 (0)