diff --git a/ios-deploy.xcodeproj/project.pbxproj b/ios-deploy.xcodeproj/project.pbxproj index 706ff87..3077328 100644 --- a/ios-deploy.xcodeproj/project.pbxproj +++ b/ios-deploy.xcodeproj/project.pbxproj @@ -26,6 +26,8 @@ /* Begin PBXFileReference section */ 7E1C00CC1C3C93AF00D686B5 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = version.h; path = src/version.h; sourceTree = SOURCE_ROOT; }; + 7E1C00CF1C3C9ABB00D686B5 /* lldb.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; name = lldb.py; path = src/scripts/lldb.py; sourceTree = SOURCE_ROOT; }; + 7E1C00D11C3C9CB000D686B5 /* lldb.py.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lldb.py.h; path = src/lldb.py.h; sourceTree = SOURCE_ROOT; }; 7E70898E1B587BF3004D23AA /* ios-deploy */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "ios-deploy"; sourceTree = BUILT_PRODUCTS_DIR; }; 7E7089991B587DE4004D23AA /* ios-deploy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "ios-deploy.c"; path = "src/ios-deploy.c"; sourceTree = SOURCE_ROOT; }; 7E70899A1B587DE4004D23AA /* errors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = errors.h; path = src/errors.h; sourceTree = SOURCE_ROOT; }; @@ -47,6 +49,14 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 7E1C00CE1C3C9A7700D686B5 /* scripts */ = { + isa = PBXGroup; + children = ( + 7E1C00CF1C3C9ABB00D686B5 /* lldb.py */, + ); + name = scripts; + sourceTree = ""; + }; 7E7089851B587BF3004D23AA = { isa = PBXGroup; children = ( @@ -67,6 +77,8 @@ 7E7089901B587BF3004D23AA /* ios-deploy */ = { isa = PBXGroup; children = ( + 7E1C00CE1C3C9A7700D686B5 /* scripts */, + 7E1C00D11C3C9CB000D686B5 /* lldb.py.h */, 7E1C00CC1C3C93AF00D686B5 /* version.h */, 7E7089991B587DE4004D23AA /* ios-deploy.c */, 7E70899A1B587DE4004D23AA /* errors.h */, @@ -91,6 +103,7 @@ isa = PBXNativeTarget; buildConfigurationList = 7E7089951B587BF3004D23AA /* Build configuration list for PBXNativeTarget "ios-deploy" */; buildPhases = ( + 7E1C00D01C3C9C0700D686B5 /* Run Script */, 7E70898A1B587BF3004D23AA /* Sources */, 7E70898B1B587BF3004D23AA /* Frameworks */, 7E70898C1B587BF3004D23AA /* CopyFiles */, @@ -136,6 +149,23 @@ }; /* End PBXProject section */ +/* Begin PBXShellScriptBuildPhase section */ + 7E1C00D01C3C9C0700D686B5 /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"\\\"# AUTO-GENERATED - DO NOT MODIFY\\n\\\"\" > src/lldb.h\nawk '{ print \"\\\"\"$0\"\\\\n\\\"\"}' src/scripts/lldb.py >> src/lldb.py.h\n"; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ 7E70898A1B587BF3004D23AA /* Sources */ = { isa = PBXSourcesBuildPhase; diff --git a/src/ios-deploy.c b/src/ios-deploy.c index 19cf0c9..5681e57 100644 --- a/src/ios-deploy.c +++ b/src/ios-deploy.c @@ -60,93 +60,10 @@ const char* lldb_prep_noninteractive_cmds = "\ * through the python interface. Also, Launch () doesn't seem to work when ran from init_module (), so we add * a command which can be used by the user to run it. */ -#define LLDB_FRUITSTRAP_MODULE CFSTR("\ -import lldb\n\ -import os\n\ -import sys\n\ -import shlex\n\ -\n\ -def connect_command(debugger, command, result, internal_dict):\n\ - # These two are passed in by the script which loads us\n\ - connect_url = internal_dict['fruitstrap_connect_url']\n\ - error = lldb.SBError()\n\ -\n\ - process = lldb.target.ConnectRemote(lldb.target.GetDebugger().GetListener(), connect_url, None, error)\n\ -\n\ - # Wait for connection to succeed\n\ - listener = lldb.target.GetDebugger().GetListener()\n\ - listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged)\n\ - events = []\n\ - state = (process.GetState() or lldb.eStateInvalid)\n\ - while state != lldb.eStateConnected:\n\ - event = lldb.SBEvent()\n\ - if listener.WaitForEvent(1, event):\n\ - state = process.GetStateFromEvent(event)\n\ - events.append(event)\n\ - else:\n\ - state = lldb.eStateInvalid\n\ -\n\ - # Add events back to queue, otherwise lldb freezes\n\ - for event in events:\n\ - listener.AddEvent(event)\n\ -\n\ -def run_command(debugger, command, result, internal_dict):\n\ - device_app = internal_dict['fruitstrap_device_app']\n\ - args = command.split('--',1)\n\ - error = lldb.SBError()\n\ - lldb.target.modules[0].SetPlatformFileSpec(lldb.SBFileSpec(device_app))\n\ - lldb.target.Launch(lldb.SBLaunchInfo(shlex.split(args[1] and args[1] or '{args}')), error)\n\ - lockedstr = ': Locked'\n\ - if lockedstr in str(error):\n\ - print('\\nDevice Locked\\n')\n\ - os._exit(254)\n\ - else:\n\ - print(str(error))\n\ -\n\ -def safequit_command(debugger, command, result, internal_dict):\n\ - process = lldb.target.process\n\ - listener = debugger.GetListener()\n\ - listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitSTDOUT | lldb.SBProcess.eBroadcastBitSTDERR)\n\ - event = lldb.SBEvent()\n\ - while True:\n\ - if listener.WaitForEvent(1, event) and lldb.SBProcess.EventIsProcessEvent(event):\n\ - state = lldb.SBProcess.GetStateFromEvent(event)\n\ - else:\n\ - state = process.GetState()\n\ -\n\ - if state == lldb.eStateRunning:\n\ - process.Detach()\n\ - os._exit(0)\n\ - elif state > lldb.eStateRunning:\n\ - os._exit(state)\n\ -\n\ -def autoexit_command(debugger, command, result, internal_dict):\n\ - process = lldb.target.process\n\ - listener = debugger.GetListener()\n\ - listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitSTDOUT | lldb.SBProcess.eBroadcastBitSTDERR)\n\ - event = lldb.SBEvent()\n\ - while True:\n\ - if listener.WaitForEvent(1, event) and lldb.SBProcess.EventIsProcessEvent(event):\n\ - state = lldb.SBProcess.GetStateFromEvent(event)\n\ - else:\n\ - state = process.GetState()\n\ -\n\ - if state == lldb.eStateExited:\n\ - os._exit(process.GetExitStatus())\n\ - elif state == lldb.eStateStopped:\n\ - debugger.HandleCommand('bt')\n\ - os._exit({exitcode_app_crash})\n\ -\n\ - stdout = process.GetSTDOUT(1024)\n\ - while stdout:\n\ - sys.stdout.write(stdout)\n\ - stdout = process.GetSTDOUT(1024)\n\ -\n\ - stderr = process.GetSTDERR(1024)\n\ - while stderr:\n\ - sys.stdout.write(stderr)\n\ - stderr = process.GetSTDERR(1024)\n\ -") +NSString* LLDB_FRUITSTRAP_MODULE = @ + #include "lldb.py.h" +; + typedef struct am_device * AMDeviceRef; mach_error_t AMDeviceSecureStartService(struct am_device *device, CFStringRef service_name, unsigned int *unknown, service_conn_t *handle); @@ -753,7 +670,7 @@ void write_lldb_prep_cmds(AMDeviceRef device, CFURLRef disk_app_url) { CFStringFindAndReplace(cmds, CFSTR("{ds_path}"), ds_path, range, 0); range.length = CFStringGetLength(cmds); - CFMutableStringRef pmodule = CFStringCreateMutableCopy(NULL, 0, LLDB_FRUITSTRAP_MODULE); + CFMutableStringRef pmodule = CFStringCreateMutableCopy(NULL, 0, (CFStringRef)LLDB_FRUITSTRAP_MODULE); CFRange rangeLLDB = { 0, CFStringGetLength(pmodule) }; CFStringRef exitcode_app_crash_str = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), exitcode_app_crash); diff --git a/src/lldb.py.h b/src/lldb.py.h new file mode 100644 index 0000000..64a40b9 --- /dev/null +++ b/src/lldb.py.h @@ -0,0 +1,341 @@ +"# AUTO-GENERATED - DO NOT MODIFY\n" +"import lldb\n" +"import os\n" +"import sys\n" +"import shlex\n" +"\n" +"def connect_command(debugger, command, result, internal_dict):\n" +" # These two are passed in by the script which loads us\n" +" connect_url = internal_dict['fruitstrap_connect_url']\n" +" error = lldb.SBError()\n" +"\n" +" process = lldb.target.ConnectRemote(lldb.target.GetDebugger().GetListener(), connect_url, None, error)\n" +"\n" +" # Wait for connection to succeed\n" +" listener = lldb.target.GetDebugger().GetListener()\n" +" listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged)\n" +" events = []\n" +" state = (process.GetState() or lldb.eStateInvalid)\n" +" while state != lldb.eStateConnected:\n" +" event = lldb.SBEvent()\n" +" if listener.WaitForEvent(1, event):\n" +" state = process.GetStateFromEvent(event)\n" +" events.append(event)\n" +" else:\n" +" state = lldb.eStateInvalid\n" +"\n" +" # Add events back to queue, otherwise lldb freezes\n" +" for event in events:\n" +" listener.AddEvent(event)\n" +"\n" +"def run_command(debugger, command, result, internal_dict):\n" +" device_app = internal_dict['fruitstrap_device_app']\n" +" args = command.split('--',1)\n" +" error = lldb.SBError()\n" +" lldb.target.modules[0].SetPlatformFileSpec(lldb.SBFileSpec(device_app))\n" +" lldb.target.Launch(lldb.SBLaunchInfo(shlex.split(args[1] and args[1] or '{args}')), error)\n" +" lockedstr = ': Locked'\n" +" if lockedstr in str(error):\n" +" print('\\nDevice Locked\\n')\n" +" os._exit(254)\n" +" else:\n" +" print(str(error))\n" +"\n" +"def safequit_command(debugger, command, result, internal_dict):\n" +" process = lldb.target.process\n" +" listener = debugger.GetListener()\n" +" listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitSTDOUT | lldb.SBProcess.eBroadcastBitSTDERR)\n" +" event = lldb.SBEvent()\n" +" while True:\n" +" if listener.WaitForEvent(1, event) and lldb.SBProcess.EventIsProcessEvent(event):\n" +" state = lldb.SBProcess.GetStateFromEvent(event)\n" +" else:\n" +" state = process.GetState()\n" +"\n" +" if state == lldb.eStateRunning:\n" +" process.Detach()\n" +" os._exit(0)\n" +" elif state > lldb.eStateRunning:\n" +" os._exit(state)\n" +"\n" +"def autoexit_command(debugger, command, result, internal_dict):\n" +" process = lldb.target.process\n" +" listener = debugger.GetListener()\n" +" listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitSTDOUT | lldb.SBProcess.eBroadcastBitSTDERR)\n" +" event = lldb.SBEvent()\n" +" while True:\n" +" if listener.WaitForEvent(1, event) and lldb.SBProcess.EventIsProcessEvent(event):\n" +" state = lldb.SBProcess.GetStateFromEvent(event)\n" +" else:\n" +" state = process.GetState()\n" +"\n" +" if state == lldb.eStateExited:\n" +" os._exit(process.GetExitStatus())\n" +" elif state == lldb.eStateStopped:\n" +" debugger.HandleCommand('bt')\n" +" os._exit({exitcode_app_crash})\n" +"\n" +" stdout = process.GetSTDOUT(1024)\n" +" while stdout:\n" +" sys.stdout.write(stdout)\n" +" stdout = process.GetSTDOUT(1024)\n" +"\n" +" stderr = process.GetSTDERR(1024)\n" +" while stderr:\n" +" sys.stdout.write(stderr)\n" +" stderr = process.GetSTDERR(1024)\n" +"import lldb\n" +"import os\n" +"import sys\n" +"import shlex\n" +"\n" +"def connect_command(debugger, command, result, internal_dict):\n" +" # These two are passed in by the script which loads us\n" +" connect_url = internal_dict['fruitstrap_connect_url']\n" +" error = lldb.SBError()\n" +"\n" +" process = lldb.target.ConnectRemote(lldb.target.GetDebugger().GetListener(), connect_url, None, error)\n" +"\n" +" # Wait for connection to succeed\n" +" listener = lldb.target.GetDebugger().GetListener()\n" +" listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged)\n" +" events = []\n" +" state = (process.GetState() or lldb.eStateInvalid)\n" +" while state != lldb.eStateConnected:\n" +" event = lldb.SBEvent()\n" +" if listener.WaitForEvent(1, event):\n" +" state = process.GetStateFromEvent(event)\n" +" events.append(event)\n" +" else:\n" +" state = lldb.eStateInvalid\n" +"\n" +" # Add events back to queue, otherwise lldb freezes\n" +" for event in events:\n" +" listener.AddEvent(event)\n" +"\n" +"def run_command(debugger, command, result, internal_dict):\n" +" device_app = internal_dict['fruitstrap_device_app']\n" +" args = command.split('--',1)\n" +" error = lldb.SBError()\n" +" lldb.target.modules[0].SetPlatformFileSpec(lldb.SBFileSpec(device_app))\n" +" lldb.target.Launch(lldb.SBLaunchInfo(shlex.split(args[1] and args[1] or '{args}')), error)\n" +" lockedstr = ': Locked'\n" +" if lockedstr in str(error):\n" +" print('\\nDevice Locked\\n')\n" +" os._exit(254)\n" +" else:\n" +" print(str(error))\n" +"\n" +"def safequit_command(debugger, command, result, internal_dict):\n" +" process = lldb.target.process\n" +" listener = debugger.GetListener()\n" +" listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitSTDOUT | lldb.SBProcess.eBroadcastBitSTDERR)\n" +" event = lldb.SBEvent()\n" +" while True:\n" +" if listener.WaitForEvent(1, event) and lldb.SBProcess.EventIsProcessEvent(event):\n" +" state = lldb.SBProcess.GetStateFromEvent(event)\n" +" else:\n" +" state = process.GetState()\n" +"\n" +" if state == lldb.eStateRunning:\n" +" process.Detach()\n" +" os._exit(0)\n" +" elif state > lldb.eStateRunning:\n" +" os._exit(state)\n" +"\n" +"def autoexit_command(debugger, command, result, internal_dict):\n" +" process = lldb.target.process\n" +" listener = debugger.GetListener()\n" +" listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitSTDOUT | lldb.SBProcess.eBroadcastBitSTDERR)\n" +" event = lldb.SBEvent()\n" +" while True:\n" +" if listener.WaitForEvent(1, event) and lldb.SBProcess.EventIsProcessEvent(event):\n" +" state = lldb.SBProcess.GetStateFromEvent(event)\n" +" else:\n" +" state = process.GetState()\n" +"\n" +" if state == lldb.eStateExited:\n" +" os._exit(process.GetExitStatus())\n" +" elif state == lldb.eStateStopped:\n" +" debugger.HandleCommand('bt')\n" +" os._exit({exitcode_app_crash})\n" +"\n" +" stdout = process.GetSTDOUT(1024)\n" +" while stdout:\n" +" sys.stdout.write(stdout)\n" +" stdout = process.GetSTDOUT(1024)\n" +"\n" +" stderr = process.GetSTDERR(1024)\n" +" while stderr:\n" +" sys.stdout.write(stderr)\n" +" stderr = process.GetSTDERR(1024)\n" +"import lldb\n" +"import os\n" +"import sys\n" +"import shlex\n" +"\n" +"def connect_command(debugger, command, result, internal_dict):\n" +" # These two are passed in by the script which loads us\n" +" connect_url = internal_dict['fruitstrap_connect_url']\n" +" error = lldb.SBError()\n" +"\n" +" process = lldb.target.ConnectRemote(lldb.target.GetDebugger().GetListener(), connect_url, None, error)\n" +"\n" +" # Wait for connection to succeed\n" +" listener = lldb.target.GetDebugger().GetListener()\n" +" listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged)\n" +" events = []\n" +" state = (process.GetState() or lldb.eStateInvalid)\n" +" while state != lldb.eStateConnected:\n" +" event = lldb.SBEvent()\n" +" if listener.WaitForEvent(1, event):\n" +" state = process.GetStateFromEvent(event)\n" +" events.append(event)\n" +" else:\n" +" state = lldb.eStateInvalid\n" +"\n" +" # Add events back to queue, otherwise lldb freezes\n" +" for event in events:\n" +" listener.AddEvent(event)\n" +"\n" +"def run_command(debugger, command, result, internal_dict):\n" +" device_app = internal_dict['fruitstrap_device_app']\n" +" args = command.split('--',1)\n" +" error = lldb.SBError()\n" +" lldb.target.modules[0].SetPlatformFileSpec(lldb.SBFileSpec(device_app))\n" +" lldb.target.Launch(lldb.SBLaunchInfo(shlex.split(args[1] and args[1] or '{args}')), error)\n" +" lockedstr = ': Locked'\n" +" if lockedstr in str(error):\n" +" print('\\nDevice Locked\\n')\n" +" os._exit(254)\n" +" else:\n" +" print(str(error))\n" +"\n" +"def safequit_command(debugger, command, result, internal_dict):\n" +" process = lldb.target.process\n" +" listener = debugger.GetListener()\n" +" listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitSTDOUT | lldb.SBProcess.eBroadcastBitSTDERR)\n" +" event = lldb.SBEvent()\n" +" while True:\n" +" if listener.WaitForEvent(1, event) and lldb.SBProcess.EventIsProcessEvent(event):\n" +" state = lldb.SBProcess.GetStateFromEvent(event)\n" +" else:\n" +" state = process.GetState()\n" +"\n" +" if state == lldb.eStateRunning:\n" +" process.Detach()\n" +" os._exit(0)\n" +" elif state > lldb.eStateRunning:\n" +" os._exit(state)\n" +"\n" +"def autoexit_command(debugger, command, result, internal_dict):\n" +" process = lldb.target.process\n" +" listener = debugger.GetListener()\n" +" listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitSTDOUT | lldb.SBProcess.eBroadcastBitSTDERR)\n" +" event = lldb.SBEvent()\n" +" while True:\n" +" if listener.WaitForEvent(1, event) and lldb.SBProcess.EventIsProcessEvent(event):\n" +" state = lldb.SBProcess.GetStateFromEvent(event)\n" +" else:\n" +" state = process.GetState()\n" +"\n" +" if state == lldb.eStateExited:\n" +" os._exit(process.GetExitStatus())\n" +" elif state == lldb.eStateStopped:\n" +" debugger.HandleCommand('bt')\n" +" os._exit({exitcode_app_crash})\n" +"\n" +" stdout = process.GetSTDOUT(1024)\n" +" while stdout:\n" +" sys.stdout.write(stdout)\n" +" stdout = process.GetSTDOUT(1024)\n" +"\n" +" stderr = process.GetSTDERR(1024)\n" +" while stderr:\n" +" sys.stdout.write(stderr)\n" +" stderr = process.GetSTDERR(1024)\n" +"import lldb\n" +"import os\n" +"import sys\n" +"import shlex\n" +"\n" +"def connect_command(debugger, command, result, internal_dict):\n" +" # These two are passed in by the script which loads us\n" +" connect_url = internal_dict['fruitstrap_connect_url']\n" +" error = lldb.SBError()\n" +"\n" +" process = lldb.target.ConnectRemote(lldb.target.GetDebugger().GetListener(), connect_url, None, error)\n" +"\n" +" # Wait for connection to succeed\n" +" listener = lldb.target.GetDebugger().GetListener()\n" +" listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged)\n" +" events = []\n" +" state = (process.GetState() or lldb.eStateInvalid)\n" +" while state != lldb.eStateConnected:\n" +" event = lldb.SBEvent()\n" +" if listener.WaitForEvent(1, event):\n" +" state = process.GetStateFromEvent(event)\n" +" events.append(event)\n" +" else:\n" +" state = lldb.eStateInvalid\n" +"\n" +" # Add events back to queue, otherwise lldb freezes\n" +" for event in events:\n" +" listener.AddEvent(event)\n" +"\n" +"def run_command(debugger, command, result, internal_dict):\n" +" device_app = internal_dict['fruitstrap_device_app']\n" +" args = command.split('--',1)\n" +" error = lldb.SBError()\n" +" lldb.target.modules[0].SetPlatformFileSpec(lldb.SBFileSpec(device_app))\n" +" lldb.target.Launch(lldb.SBLaunchInfo(shlex.split(args[1] and args[1] or '{args}')), error)\n" +" lockedstr = ': Locked'\n" +" if lockedstr in str(error):\n" +" print('\\nDevice Locked\\n')\n" +" os._exit(254)\n" +" else:\n" +" print(str(error))\n" +"\n" +"def safequit_command(debugger, command, result, internal_dict):\n" +" process = lldb.target.process\n" +" listener = debugger.GetListener()\n" +" listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitSTDOUT | lldb.SBProcess.eBroadcastBitSTDERR)\n" +" event = lldb.SBEvent()\n" +" while True:\n" +" if listener.WaitForEvent(1, event) and lldb.SBProcess.EventIsProcessEvent(event):\n" +" state = lldb.SBProcess.GetStateFromEvent(event)\n" +" else:\n" +" state = process.GetState()\n" +"\n" +" if state == lldb.eStateRunning:\n" +" process.Detach()\n" +" os._exit(0)\n" +" elif state > lldb.eStateRunning:\n" +" os._exit(state)\n" +"\n" +"def autoexit_command(debugger, command, result, internal_dict):\n" +" process = lldb.target.process\n" +" listener = debugger.GetListener()\n" +" listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitSTDOUT | lldb.SBProcess.eBroadcastBitSTDERR)\n" +" event = lldb.SBEvent()\n" +" while True:\n" +" if listener.WaitForEvent(1, event) and lldb.SBProcess.EventIsProcessEvent(event):\n" +" state = lldb.SBProcess.GetStateFromEvent(event)\n" +" else:\n" +" state = process.GetState()\n" +"\n" +" if state == lldb.eStateExited:\n" +" os._exit(process.GetExitStatus())\n" +" elif state == lldb.eStateStopped:\n" +" debugger.HandleCommand('bt')\n" +" os._exit({exitcode_app_crash})\n" +"\n" +" stdout = process.GetSTDOUT(1024)\n" +" while stdout:\n" +" sys.stdout.write(stdout)\n" +" stdout = process.GetSTDOUT(1024)\n" +"\n" +" stderr = process.GetSTDERR(1024)\n" +" while stderr:\n" +" sys.stdout.write(stderr)\n" +" stderr = process.GetSTDERR(1024)\n" diff --git a/src/scripts/lldb.py b/src/scripts/lldb.py new file mode 100644 index 0000000..ec02219 --- /dev/null +++ b/src/scripts/lldb.py @@ -0,0 +1,85 @@ +import lldb +import os +import sys +import shlex + +def connect_command(debugger, command, result, internal_dict): + # These two are passed in by the script which loads us + connect_url = internal_dict['fruitstrap_connect_url'] + error = lldb.SBError() + + process = lldb.target.ConnectRemote(lldb.target.GetDebugger().GetListener(), connect_url, None, error) + + # Wait for connection to succeed + listener = lldb.target.GetDebugger().GetListener() + listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged) + events = [] + state = (process.GetState() or lldb.eStateInvalid) + while state != lldb.eStateConnected: + event = lldb.SBEvent() + if listener.WaitForEvent(1, event): + state = process.GetStateFromEvent(event) + events.append(event) + else: + state = lldb.eStateInvalid + + # Add events back to queue, otherwise lldb freezes + for event in events: + listener.AddEvent(event) + +def run_command(debugger, command, result, internal_dict): + device_app = internal_dict['fruitstrap_device_app'] + args = command.split('--',1) + error = lldb.SBError() + lldb.target.modules[0].SetPlatformFileSpec(lldb.SBFileSpec(device_app)) + lldb.target.Launch(lldb.SBLaunchInfo(shlex.split(args[1] and args[1] or '{args}')), error) + lockedstr = ': Locked' + if lockedstr in str(error): + print('\\nDevice Locked\\n') + os._exit(254) + else: + print(str(error)) + +def safequit_command(debugger, command, result, internal_dict): + process = lldb.target.process + listener = debugger.GetListener() + listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitSTDOUT | lldb.SBProcess.eBroadcastBitSTDERR) + event = lldb.SBEvent() + while True: + if listener.WaitForEvent(1, event) and lldb.SBProcess.EventIsProcessEvent(event): + state = lldb.SBProcess.GetStateFromEvent(event) + else: + state = process.GetState() + + if state == lldb.eStateRunning: + process.Detach() + os._exit(0) + elif state > lldb.eStateRunning: + os._exit(state) + +def autoexit_command(debugger, command, result, internal_dict): + process = lldb.target.process + listener = debugger.GetListener() + listener.StartListeningForEvents(process.GetBroadcaster(), lldb.SBProcess.eBroadcastBitStateChanged | lldb.SBProcess.eBroadcastBitSTDOUT | lldb.SBProcess.eBroadcastBitSTDERR) + event = lldb.SBEvent() + while True: + if listener.WaitForEvent(1, event) and lldb.SBProcess.EventIsProcessEvent(event): + state = lldb.SBProcess.GetStateFromEvent(event) + else: + state = process.GetState() + + if state == lldb.eStateExited: + os._exit(process.GetExitStatus()) + elif state == lldb.eStateStopped: + debugger.HandleCommand('bt') + os._exit({exitcode_app_crash}) + + stdout = process.GetSTDOUT(1024) + while stdout: + sys.stdout.write(stdout) + stdout = process.GetSTDOUT(1024) + + stderr = process.GetSTDERR(1024) + while stderr: + sys.stdout.write(stderr) + stderr = process.GetSTDERR(1024)