@@ -19,14 +19,15 @@ def connect_command(debugger, command, result, internal_dict):
19
19
listener = lldb .SBListener ('iosdeploy_listener' )
20
20
21
21
listener .StartListeningForEventClass (debugger ,
22
- lldb .SBTarget .GetBroadcasterClassName (),
22
+ lldb .SBProcess .GetBroadcasterClassName (),
23
23
lldb .SBProcess .eBroadcastBitStateChanged | lldb .SBProcess .eBroadcastBitSTDOUT | lldb .SBProcess .eBroadcastBitSTDERR )
24
24
25
25
process = debugger .GetSelectedTarget ().ConnectRemote (listener , connect_url , None , error )
26
26
27
27
# Wait for connection to succeed
28
28
events = []
29
29
state = (process .GetState () or lldb .eStateInvalid )
30
+
30
31
while state != lldb .eStateConnected :
31
32
event = lldb .SBEvent ()
32
33
if listener .WaitForEvent (1 , event ):
@@ -82,6 +83,16 @@ def safequit_command(debugger, command, result, internal_dict):
82
83
print ('\\ nApplication has not been launched\\ n' )
83
84
os ._exit (1 )
84
85
86
+
87
+ def print_stacktrace (thread ):
88
+ # Somewhere between Xcode-13.2.1 and Xcode-13.3 lldb starts to throw an error during printing of backtrace.
89
+ # Manually write the backtrace out so we don't just get 'invalid thread'.
90
+ sys .stdout .write (' ' + str (thread ) + '\\ n' )
91
+ for frame in thread :
92
+ out = lldb .SBStream ()
93
+ frame .GetDescription (out )
94
+ sys .stdout .write (' ' * 4 + out .GetData ())
95
+
85
96
def autoexit_command (debugger , command , result , internal_dict ):
86
97
global listener
87
98
process = debugger .GetSelectedTarget ().process
@@ -102,8 +113,10 @@ def autoexit_command(debugger, command, result, internal_dict):
102
113
detectDeadlockTimeout = {detect_deadlock_timeout }
103
114
printBacktraceTime = time .time () + detectDeadlockTimeout if detectDeadlockTimeout > 0 else None
104
115
105
- # This line prevents internal lldb listener from processing STDOUT/STDERR messages. Without it, an order of log writes is incorrect sometimes
106
- debugger .GetListener ().StopListeningForEvents (process .GetBroadcaster (), lldb .SBProcess .eBroadcastBitSTDOUT | lldb .SBProcess .eBroadcastBitSTDERR )
116
+ # This line prevents internal lldb listener from processing STDOUT/STDERR/StateChanged messages.
117
+ # Without it, an order of log writes is incorrect sometimes
118
+ debugger .GetListener ().StopListeningForEvents (process .GetBroadcaster (),
119
+ lldb .SBProcess .eBroadcastBitSTDOUT | lldb .SBProcess .eBroadcastBitSTDERR | lldb .SBProcess .eBroadcastBitStateChanged )
107
120
108
121
event = lldb .SBEvent ()
109
122
@@ -131,7 +144,7 @@ def CloseOut():
131
144
out .close ()
132
145
if (err ):
133
146
err .close ()
134
-
147
+
135
148
while True :
136
149
if listener .WaitForEvent (1 , event ) and lldb .SBProcess .EventIsProcessEvent (event ):
137
150
state = lldb .SBProcess .GetStateFromEvent (event )
@@ -162,12 +175,12 @@ def CloseOut():
162
175
# On iOS-16 we receive them with stop reason none.
163
176
continue
164
177
sys .stdout .write ( '\\ nPROCESS_STOPPED\\ n' )
165
- debugger . HandleCommand ( 'bt' )
178
+ print_stacktrace ( process . GetSelectedThread () )
166
179
CloseOut ()
167
180
os ._exit ({exitcode_app_crash })
168
181
elif state == lldb .eStateCrashed :
169
182
sys .stdout .write ( '\\ nPROCESS_CRASHED\\ n' )
170
- debugger . HandleCommand ( 'bt' )
183
+ print_stacktrace ( process . GetSelectedThread () )
171
184
CloseOut ()
172
185
os ._exit ({exitcode_app_crash })
173
186
elif state == lldb .eStateDetached :
@@ -178,6 +191,8 @@ def CloseOut():
178
191
printBacktraceTime = None
179
192
sys .stdout .write ( '\\ nPRINT_BACKTRACE_TIMEOUT\\ n' )
180
193
debugger .HandleCommand ('process interrupt' )
181
- debugger .HandleCommand ('bt all' )
194
+ for thread in process :
195
+ print_stacktrace (thread )
196
+ sys .stdout .write ('\\ n' )
182
197
debugger .HandleCommand ('continue' )
183
198
printBacktraceTime = time .time () + 5
0 commit comments