Skip to content

Instantly share code, notes, and snippets.

@larryhou
Last active April 10, 2018 07:16
Show Gist options
  • Save larryhou/d1ac8db8693523da4dc19745357c24a5 to your computer and use it in GitHub Desktop.
Save larryhou/d1ac8db8693523da4dc19745357c24a5 to your computer and use it in GitHub Desktop.
Bugfix for unity game crash on iOS Airplay

Bugfix for unity game crash on iOS Airplay

python unity_airplay_bugfix.py -i -f ./iOSProj/Classes/Unity/DisplayManager.mm
Incident Identifier: C0C2D616-E91B-40FA-8A95-B011F00B2707
CrashReporter Key:   0f5b8e228d89ea826e3793c64583ebfa05d27b11
Hardware Model:      iPhone9,2
Process:             warsong1 [2257]
Path:                /private/var/containers/Bundle/Application/005FA5C2-9B1C-464D-AF8D-3D7D4D95EA0B/warsong1.app/warsong1
Identifier:          com.sixjoy.warsong1
Version:             98922 (1.1.145)
Code Type:           ARM-64 (Native)
Role:                Foreground
Parent Process:      launchd [1]
Coalition:           com.sixjoy.warsong1 [1745]


Date/Time:           2018-04-10 13:06:58.4521 +0800
Launch Time:         2018-04-10 13:06:57.7476 +0800
OS Version:          iPhone OS 11.3 (15E216)
Baseband Version:    3.66.00
Report Version:      104

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000078
VM Region Info: 0x78 is not in any region.  Bytes before following region: 4333354888
      REGION TYPE                      START - END             [ VSIZE] PRT/MAX SHRMOD  REGION DETAIL
      UNUSED SPACE AT START
--->  
      __TEXT                 000000010249c000-0000000105820000 [ 51.5M] r-x/r-x SM=COW  ....app/warsong1

Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [0]
Triggered by Thread:  0

Filtered syslog:
None found

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   warsong1                      	0x0000000104192588 UnityUpdateDisplayList + 30369160 (LibEntryPoint.mm:578)
1   warsong1                      	0x00000001024ad658 -[DisplayManager updateDisplayListInUnity] + 71256 (DisplayManager.mm:330)
2   warsong1                      	0x00000001024ad9fc -[DisplayManager screenDidConnect:] + 72188 (DisplayManager.mm:369)
3   CoreFoundation                	0x0000000182e70c3c __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 20
4   CoreFoundation                	0x0000000182e701b8 _CFXRegistrationPost + 428
5   CoreFoundation                	0x0000000182e6ff14 ___CFXNotificationPost_block_invoke + 216
6   CoreFoundation                	0x0000000182eed84c -[_CFXNotificationRegistrar find:object:observer:enumerator:] + 1408
7   CoreFoundation                	0x0000000182da6f38 _CFXNotificationPost + 384
8   Foundation                    	0x0000000183817bbc -[NSNotificationCenter postNotificationName:object:userInfo:] + 68
9   UIKit                         	0x000000018ca6ed24 +[UIScreen _FBSDisplayConfigurationConnected:andNotify:] + 280
10  UIKit                         	0x000000018ca75564 -[UIApplication workspace:didCreateScene:withTransitionContext:completion:] + 292
11  UIKit                         	0x000000018ca753ac -[UIApplicationSceneClientAgent scene:didInitializeWithEvent:completion:] + 364
12  FrontBoardServices            	0x00000001856dc470 -[FBSSceneImpl _didCreateWithTransitionContext:completion:] + 364
13  FrontBoardServices            	0x00000001856e4d6c __56-[FBSWorkspace client:handleCreateScene:withCompletion:]_block_invoke_2 + 224
14  libdispatch.dylib             	0x00000001827d0ae4 _dispatch_client_callout + 16
15  libdispatch.dylib             	0x00000001827d81f4 _dispatch_block_invoke_direct$VARIANT$mp + 224
16  FrontBoardServices            	0x0000000185710878 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 36
17  FrontBoardServices            	0x000000018571051c -[FBSSerialQueue _performNext] + 404
18  FrontBoardServices            	0x0000000185710ab8 -[FBSSerialQueue _performNextFromRunLoopSource] + 56
19  CoreFoundation                	0x0000000182e87404 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
20  CoreFoundation                	0x0000000182e86c2c __CFRunLoopDoSources0 + 276
21  CoreFoundation                	0x0000000182e8479c __CFRunLoopRun + 1204
22  CoreFoundation                	0x0000000182da4da8 CFRunLoopRunSpecific + 552
23  GraphicsServices              	0x0000000184d87020 GSEventRunModal + 100
24  UIKit                         	0x000000018cd8578c UIApplicationMain + 236
25  warsong1                      	0x00000001024a0e00 main + 19968 (main.mm:33)
26  libdyld.dylib                 	0x0000000182835fc0 start + 4
#!/usr/bin/env python
#encoding:utf-8
import argparse, sys, re, os
# [[NSNotificationCenter defaultCenter] addObserver: self
# selector: @selector(screenDidConnect:)
# name: UIScreenDidConnectNotification
# object: nil
# ];
# [[NSNotificationCenter defaultCenter] addObserver: self
# selector: @selector(screenDidDisconnect:)
# name: UIScreenDidDisconnectNotification
# object: nil
# ];
def main():
arguments = argparse.ArgumentParser()
arguments.add_argument('--display-manager-file', '-f', required=True, help='传入<Classes/Unity/DisplayManager.mm>路径')
arguments.add_argument('--replace-in-place', '-i', action='store_true', help='原路径替换文件,并备份源文件为<DisplayManager.mm.bak>')
params = arguments.parse_args(sys.argv[1:])
script_path = os.path.abspath(params.display_manager_file)
assert os.path.exists(script_path)
detect_pattern = re.compile(r'^\s+\[\[NSNotificationCenter\s+defaultCenter\]\s+addObserver:\s+self')
target_pattern = re.compile(r'\@selector\(screenDid(Disc|C)onnect:\)', re.MULTILINE)
import tempfile
output = open(tempfile.mktemp('DisplayManager.mm'), 'w+')
source_script = open(script_path, 'r+')
logic_code = None
bracket_num, found, bug_num = None, False, 0
for line in source_script.readlines():
if detect_pattern.search(line):
bracket_num, found = 0, True
logic_code = ''
bug_num += 1
if found:
logic_code += line
print '-%s'%(re.sub(r'\n$', '', line))
for n in range(len(line)):
if line[n] == '[': bracket_num += 1
if line[n] == ']': bracket_num -= 1
if bracket_num != 0: continue
else:
found = False
if target_pattern.search(logic_code):
print logic_code
continue
else:
line = logic_code
output.write(line)
def clean_up():
output.close()
os.remove(output.name)
source_script.close()
if bug_num == 0:
print '[SKIP] no pattern found'
clean_up()
return
if params.replace_in_place:
with open(script_path + '.bak', 'w') as fp:
source_script.seek(0)
fp.write(source_script.read())
fp.close()
source_script.close()
with open(script_path, 'w') as fp:
output.seek(0)
fp.write(output.read())
fp.close()
else:
output.seek(0)
print output.read()
clean_up()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment