Skip to content

Commit f043e66

Browse files
committed
[lldb/crashlog] Make register output match lldb ordering in legacy mode
This patch changes the way we dump the registers from the legacy crashlog command to make sure that the ordering matches the one from lldb. rdar://109172073 Differential Revision: https://reviews.llvm.org/D156919 Signed-off-by: Med Ismail Bennani <[email protected]>
1 parent c053345 commit f043e66

File tree

1 file changed

+62
-11
lines changed

1 file changed

+62
-11
lines changed

lldb/examples/python/crashlog.py

Lines changed: 62 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
sys.exit(1)
7272

7373
from lldb.utils import symbolication
74+
from lldb.plugins.scripted_process import INTEL64_GPR, ARM64_GPR
7475

7576

7677
def read_plist(s):
@@ -84,7 +85,7 @@ class CrashLog(symbolication.Symbolicator):
8485
class Thread:
8586
"""Class that represents a thread in a darwin crash log"""
8687

87-
def __init__(self, index, app_specific_backtrace):
88+
def __init__(self, index, app_specific_backtrace, arch):
8889
self.index = index
8990
self.id = index
9091
self.images = list()
@@ -96,8 +97,56 @@ def __init__(self, index, app_specific_backtrace):
9697
self.queue = None
9798
self.crashed = False
9899
self.app_specific_backtrace = app_specific_backtrace
100+
self.arch = arch
101+
102+
def dump_registers(self, prefix=""):
103+
registers_info = None
104+
sorted_registers = {}
105+
106+
def sort_dict(d):
107+
sorted_keys = list(d.keys())
108+
sorted_keys.sort()
109+
return {k: d[k] for k in sorted_keys}
110+
111+
if self.arch:
112+
if "x86_64" == self.arch:
113+
registers_info = INTEL64_GPR
114+
elif "arm64" in self.arch:
115+
registers_info = ARM64_GPR
116+
else:
117+
print("unknown target architecture: %s" % self.arch)
118+
return
99119

100-
def dump(self, prefix):
120+
# Add registers available in the register information dictionary.
121+
for reg_info in registers_info:
122+
reg_name = None
123+
if reg_info["name"] in self.registers:
124+
reg_name = reg_info["name"]
125+
elif (
126+
"generic" in reg_info and reg_info["generic"] in self.registers
127+
):
128+
reg_name = reg_info["generic"]
129+
else:
130+
# Skip register that are present in the register information dictionary but not present in the report.
131+
continue
132+
133+
reg_val = self.registers[reg_name]
134+
sorted_registers[reg_name] = reg_val
135+
136+
unknown_parsed_registers = {}
137+
for reg_name in self.registers:
138+
if reg_name not in sorted_registers:
139+
unknown_parsed_registers[reg_name] = self.registers[reg_name]
140+
141+
sorted_registers.update(sort_dict(unknown_parsed_registers))
142+
143+
else:
144+
sorted_registers = sort_dict(self.registers)
145+
146+
for reg_name, reg_val in sorted_registers.items():
147+
print("%s %-8s = %#16.16x" % (prefix, reg_name, reg_val))
148+
149+
def dump(self, prefix=""):
101150
if self.app_specific_backtrace:
102151
print(
103152
"%Application Specific Backtrace[%u] %s"
@@ -111,8 +160,7 @@ def dump(self, prefix):
111160
frame.dump(prefix + " ")
112161
if self.registers:
113162
print("%s Registers:" % (prefix))
114-
for reg in self.registers.keys():
115-
print("%s %-8s = %#16.16x" % (prefix, reg, self.registers[reg]))
163+
self.dump_registers(prefix)
116164

117165
def dump_symbolicated(self, crash_log, options):
118166
this_thread_crashed = self.app_specific_backtrace
@@ -194,8 +242,7 @@ def dump_symbolicated(self, crash_log, options):
194242
print(frame)
195243
if self.registers:
196244
print()
197-
for reg in self.registers.keys():
198-
print(" %-8s = %#16.16x" % (reg, self.registers[reg]))
245+
self.dump_registers()
199246
elif self.crashed:
200247
print()
201248
print("No thread state (register information) available")
@@ -655,7 +702,7 @@ def parse_frames(self, thread, json_frames):
655702
def parse_threads(self, json_threads):
656703
idx = 0
657704
for json_thread in json_threads:
658-
thread = self.crashlog.Thread(idx, False)
705+
thread = self.crashlog.Thread(idx, False, self.crashlog.process_arch)
659706
if "name" in json_thread:
660707
thread.name = json_thread["name"]
661708
thread.reason = json_thread["name"]
@@ -749,7 +796,7 @@ def parse_asi_backtrace(self, thread, bt):
749796

750797
def parse_app_specific_backtraces(self, json_app_specific_bts):
751798
for idx, backtrace in enumerate(json_app_specific_bts):
752-
thread = self.crashlog.Thread(idx, True)
799+
thread = self.crashlog.Thread(idx, True, self.crashlog.process_arch)
753800
thread.queue = "Application Specific Backtrace"
754801
if self.parse_asi_backtrace(thread, backtrace):
755802
self.crashlog.threads.append(thread)
@@ -1008,7 +1055,9 @@ def parse_normal(self, line):
10081055
self.app_specific_backtrace = False
10091056
self.parse_mode = CrashLogParseMode.THREAD
10101057
thread_idx = int(thread_match.group(1))
1011-
self.thread = self.crashlog.Thread(thread_idx, False)
1058+
self.thread = self.crashlog.Thread(
1059+
thread_idx, False, self.crashlog.process_arch
1060+
)
10121061
return
10131062
return
10141063
elif line.startswith("Binary Images:"):
@@ -1020,12 +1069,14 @@ def parse_normal(self, line):
10201069
self.parse_mode = CrashLogParseMode.THREAD
10211070
self.app_specific_backtrace = True
10221071
idx = int(app_backtrace_match.group(1))
1023-
self.thread = self.crashlog.Thread(idx, True)
1072+
self.thread = self.crashlog.Thread(
1073+
idx, True, self.crashlog.process_arch
1074+
)
10241075
elif line.startswith("Last Exception Backtrace:"): # iOS
10251076
self.parse_mode = CrashLogParseMode.THREAD
10261077
self.app_specific_backtrace = True
10271078
idx = 1
1028-
self.thread = self.crashlog.Thread(idx, True)
1079+
self.thread = self.crashlog.Thread(idx, True, self.crashlog.process_arch)
10291080
self.crashlog.info_lines.append(line.strip())
10301081

10311082
def parse_thread(self, line):

0 commit comments

Comments
 (0)