diff --git a/commands/FBClassDump.py b/commands/FBClassDump.py index 3615dd0..c0461a6 100644 --- a/commands/FBClassDump.py +++ b/commands/FBClassDump.py @@ -134,7 +134,7 @@ def run(self, arguments, options): [dict setObject:types forKey:@"signature"]; } - RETURN(dict); + RETURN_JSON(dict); """ command = string.Template(tmpString).substitute(block=block) json = fb.evaluate(command) @@ -260,7 +260,7 @@ def getMethods(klass): [result addObject:m]; } - RETURN(result); + RETURN_JSON(result); """ command = string.Template(tmpString).substitute(cls=klass) methods = fb.evaluate(command) @@ -302,10 +302,10 @@ def getProperties(klass): NSMutableDictionary *dict = (id)[NSMutableDictionary dictionary]; char *name = (char *)property_getName(props[i]); - [dict setObject:(id)[NSString stringWithUTF8String:name] forKey:@"name"]; + [dict setObject:(id)[NSString stringWithUTF8String:name] forKey:(id)@"name"]; char *attrstr = (char *)property_getAttributes(props[i]); - [dict setObject:(id)[NSString stringWithUTF8String:attrstr] forKey:@"attributes_string"]; + [dict setObject:(id)[NSString stringWithUTF8String:attrstr] forKey:(id)@"attributes_string"]; NSMutableDictionary *attrsDict = (id)[NSMutableDictionary dictionary]; unsigned int pcount; @@ -313,13 +313,13 @@ def getProperties(klass): for (int i = 0; i < pcount; i++) { NSString *name = (id)[NSString stringWithUTF8String:(char *)attrs[i].name]; NSString *value = (id)[NSString stringWithUTF8String:(char *)attrs[i].value]; - [attrsDict setObject:value forKey:name]; + [attrsDict setObject:value forKey:(id)name]; } - [dict setObject:attrsDict forKey:@"attributes"]; + [dict setObject:attrsDict forKey:(id)@"attributes"]; [result addObject:dict]; } - RETURN(result); + RETURN_JSON(result); """ command = string.Template(tmpString).substitute(cls=klass) propsJson = fb.evaluate(command) diff --git a/commands/FBDebugCommands.py b/commands/FBDebugCommands.py index 4b43c4d..4aedf49 100644 --- a/commands/FBDebugCommands.py +++ b/commands/FBDebugCommands.py @@ -7,6 +7,7 @@ import sys import os import re +import string def lldbcommands(): return [ @@ -19,6 +20,7 @@ def lldbcommands(): FBMethodBreakpointDisableCommand(), FBHeapFromCommand(), FBSequenceCommand(), + FBEvaluateFile(), ] class FBWatchInstanceVariableCommand(fb.FBCommand): @@ -456,3 +458,42 @@ def run(self, arguments, options): self.result.SetError(object.GetError()) self.result.SetStatus(object.GetStatus()) return + +class FBEvaluateFile(fb.FBCommand): + def name(self): + return 'evalfile' + + def description(self): + return 'Run expression from a file.' + + def args(self): + return [ fb.FBCommandArgument(arg='file path', type='string', help='file of source code') ] + + def getValue(self, arguments, index): + if index >= len(arguments): + return None + return arguments[index] + + def run(self, arguments, options): + file_path = arguments[0].split()[0] + if not file_path: + print "Error: Missing file" + return + + file = open(file_path, 'r') + source = file.read() + source = string.Template(source).substitute( + arg0=self.getValue(arguments, 1), + arg1=self.getValue(arguments, 2), + arg2=self.getValue(arguments, 3), + arg3=self.getValue(arguments, 4) + ) + + ret = fb.evaluate(source) + # if ret is not an address then print it directly + if ret[0:2] != '0x': + print ret + else: + command = 'po {}'.format(ret) + lldb.debugger.HandleCommand(command) + diff --git a/fblldbbase.py b/fblldbbase.py index dae6897..48bcb1c 100755 --- a/fblldbbase.py +++ b/fblldbbase.py @@ -146,17 +146,17 @@ def evaluateCStringExpression(expression, printErrors=True): (obj != nil && ((bool)[NSJSONSerialization isValidJSONObject:obj] ||\ (bool)[obj isKindOfClass:[NSString class]] ||\ (bool)[obj isKindOfClass:[NSNumber class]])) -#define RETURN(ret) ({\ + +#define RETURN_JSON(ret) ({\ if (!IS_JSON_OBJ(ret)) {\ (void)[NSException raise:@"Invalid RETURN argument" format:@""];\ }\ - NSDictionary *__dict = @{@"return":ret};\ + NSDictionary *__dict = @{(id)@"return":ret};\ NSData *__data = (id)[NSJSONSerialization dataWithJSONObject:__dict options:0 error:NULL];\ NSString *__str = (id)[[NSString alloc] initWithData:__data encoding:4];\ (char *)[__str UTF8String];}) -#define RETURNCString(ret)\ - ({NSString *___cstring_ret = [NSString stringWithUTF8String:ret];\ - RETURN(___cstring_ret);}) + +#define RETURN(ret) ret """ def check_expr(expr): @@ -176,16 +176,20 @@ def evaluate(expr): if not ret.GetError().Success(): print ret.GetError() return None + + isJson = expr.strip().split(';')[-2].find('RETURN_JSON') != -1 + if not isJson: + return ret.GetValue() + + process = lldb.debugger.GetSelectedTarget().GetProcess() + error = lldb.SBError() + ret = process.ReadCStringFromMemory(int(ret.GetValue(), 16), 2**20, error) + if not error.Success(): + print error + return None else: - process = lldb.debugger.GetSelectedTarget().GetProcess() - error = lldb.SBError() - ret = process.ReadCStringFromMemory(int(ret.GetValue(), 16), 2**20, error) - if not error.Success(): - print error - return None - else: - ret = json.loads(ret) - return ret['return'] + ret = json.loads(ret) + return ret['return'] def currentLanguage(): return lldb.debugger.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().GetCompileUnit().GetLanguage()