71
71
sys .exit (1 )
72
72
73
73
from lldb .utils import symbolication
74
+ from lldb .plugins .scripted_process import INTEL64_GPR , ARM64_GPR
74
75
75
76
76
77
def read_plist (s ):
@@ -84,7 +85,7 @@ class CrashLog(symbolication.Symbolicator):
84
85
class Thread :
85
86
"""Class that represents a thread in a darwin crash log"""
86
87
87
- def __init__ (self , index , app_specific_backtrace ):
88
+ def __init__ (self , index , app_specific_backtrace , arch ):
88
89
self .index = index
89
90
self .id = index
90
91
self .images = list ()
@@ -96,8 +97,56 @@ def __init__(self, index, app_specific_backtrace):
96
97
self .queue = None
97
98
self .crashed = False
98
99
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
99
119
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 = "" ):
101
150
if self .app_specific_backtrace :
102
151
print (
103
152
"%Application Specific Backtrace[%u] %s"
@@ -111,8 +160,7 @@ def dump(self, prefix):
111
160
frame .dump (prefix + " " )
112
161
if self .registers :
113
162
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 )
116
164
117
165
def dump_symbolicated (self , crash_log , options ):
118
166
this_thread_crashed = self .app_specific_backtrace
@@ -194,8 +242,7 @@ def dump_symbolicated(self, crash_log, options):
194
242
print (frame )
195
243
if self .registers :
196
244
print ()
197
- for reg in self .registers .keys ():
198
- print (" %-8s = %#16.16x" % (reg , self .registers [reg ]))
245
+ self .dump_registers ()
199
246
elif self .crashed :
200
247
print ()
201
248
print ("No thread state (register information) available" )
@@ -655,7 +702,7 @@ def parse_frames(self, thread, json_frames):
655
702
def parse_threads (self , json_threads ):
656
703
idx = 0
657
704
for json_thread in json_threads :
658
- thread = self .crashlog .Thread (idx , False )
705
+ thread = self .crashlog .Thread (idx , False , self . crashlog . process_arch )
659
706
if "name" in json_thread :
660
707
thread .name = json_thread ["name" ]
661
708
thread .reason = json_thread ["name" ]
@@ -749,7 +796,7 @@ def parse_asi_backtrace(self, thread, bt):
749
796
750
797
def parse_app_specific_backtraces (self , json_app_specific_bts ):
751
798
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 )
753
800
thread .queue = "Application Specific Backtrace"
754
801
if self .parse_asi_backtrace (thread , backtrace ):
755
802
self .crashlog .threads .append (thread )
@@ -1008,7 +1055,9 @@ def parse_normal(self, line):
1008
1055
self .app_specific_backtrace = False
1009
1056
self .parse_mode = CrashLogParseMode .THREAD
1010
1057
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
+ )
1012
1061
return
1013
1062
return
1014
1063
elif line .startswith ("Binary Images:" ):
@@ -1020,12 +1069,14 @@ def parse_normal(self, line):
1020
1069
self .parse_mode = CrashLogParseMode .THREAD
1021
1070
self .app_specific_backtrace = True
1022
1071
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
+ )
1024
1075
elif line .startswith ("Last Exception Backtrace:" ): # iOS
1025
1076
self .parse_mode = CrashLogParseMode .THREAD
1026
1077
self .app_specific_backtrace = True
1027
1078
idx = 1
1028
- self .thread = self .crashlog .Thread (idx , True )
1079
+ self .thread = self .crashlog .Thread (idx , True , self . crashlog . process_arch )
1029
1080
self .crashlog .info_lines .append (line .strip ())
1030
1081
1031
1082
def parse_thread (self , line ):
0 commit comments