Skip to content

Commit b325443

Browse files
authored
Add workaround needed for Xcode-13.3+ for --noninteract crashes, where lldb is not able to print backtrace (#558)
1 parent 24c9efb commit b325443

File tree

1 file changed

+22
-7
lines changed

1 file changed

+22
-7
lines changed

src/scripts/lldb.py

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@ def connect_command(debugger, command, result, internal_dict):
1919
listener = lldb.SBListener('iosdeploy_listener')
2020

2121
listener.StartListeningForEventClass(debugger,
22-
lldb.SBTarget.GetBroadcasterClassName(),
22+
lldb.SBProcess.GetBroadcasterClassName(),
2323
lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitSTDOUT | lldb.SBProcess.eBroadcastBitSTDERR)
2424

2525
process = debugger.GetSelectedTarget().ConnectRemote(listener, connect_url, None, error)
2626

2727
# Wait for connection to succeed
2828
events = []
2929
state = (process.GetState() or lldb.eStateInvalid)
30+
3031
while state != lldb.eStateConnected:
3132
event = lldb.SBEvent()
3233
if listener.WaitForEvent(1, event):
@@ -82,6 +83,16 @@ def safequit_command(debugger, command, result, internal_dict):
8283
print('\\nApplication has not been launched\\n')
8384
os._exit(1)
8485

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+
8596
def autoexit_command(debugger, command, result, internal_dict):
8697
global listener
8798
process = debugger.GetSelectedTarget().process
@@ -102,8 +113,10 @@ def autoexit_command(debugger, command, result, internal_dict):
102113
detectDeadlockTimeout = {detect_deadlock_timeout}
103114
printBacktraceTime = time.time() + detectDeadlockTimeout if detectDeadlockTimeout > 0 else None
104115

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 )
107120

108121
event = lldb.SBEvent()
109122

@@ -131,7 +144,7 @@ def CloseOut():
131144
out.close()
132145
if (err):
133146
err.close()
134-
147+
135148
while True:
136149
if listener.WaitForEvent(1, event) and lldb.SBProcess.EventIsProcessEvent(event):
137150
state = lldb.SBProcess.GetStateFromEvent(event)
@@ -162,12 +175,12 @@ def CloseOut():
162175
# On iOS-16 we receive them with stop reason none.
163176
continue
164177
sys.stdout.write( '\\nPROCESS_STOPPED\\n' )
165-
debugger.HandleCommand('bt')
178+
print_stacktrace(process.GetSelectedThread())
166179
CloseOut()
167180
os._exit({exitcode_app_crash})
168181
elif state == lldb.eStateCrashed:
169182
sys.stdout.write( '\\nPROCESS_CRASHED\\n' )
170-
debugger.HandleCommand('bt')
183+
print_stacktrace(process.GetSelectedThread())
171184
CloseOut()
172185
os._exit({exitcode_app_crash})
173186
elif state == lldb.eStateDetached:
@@ -178,6 +191,8 @@ def CloseOut():
178191
printBacktraceTime = None
179192
sys.stdout.write( '\\nPRINT_BACKTRACE_TIMEOUT\\n' )
180193
debugger.HandleCommand('process interrupt')
181-
debugger.HandleCommand('bt all')
194+
for thread in process:
195+
print_stacktrace(thread)
196+
sys.stdout.write('\\n')
182197
debugger.HandleCommand('continue')
183198
printBacktraceTime = time.time() + 5

0 commit comments

Comments
 (0)