How to log all methods used in iOS app

北城余情 提交于 2019-11-26 03:48:29

问题


I\'m taking over the development of an iPad app for a client. There\'s a substantial amount of work that\'s already been done and I\'m trying to piece together how the whole thing is designed to run.

One of the things I\'d like to do is log which methods get called when the app runs. I\'ve seen a custom DTrace script that\'s meant to log all methods from startup, but when I run it in Instruments I get no results.

What\'s the best way of logging the methods?


回答1:


Inspired by tc's answer to a similar question here, I put together a debug breakpoint action that will log out the class and method name for every time objc_msgSend() is triggered in your application. This works similarly to the DTrace script I described in this answer.

To enable this breakpoint action, create a new symbolic breakpoint (in Xcode 4, go to the breakpoint navigator and create a new symbolic breakpoint using the plus at the bottom left of the window). Have the symbol be objc_msgSend, set it to automatically continue after evaluating actions, and set the action to be a debugger command using the following:

printf "[%s %s]\n", (char *)object_getClassName(*(long*)($esp+4)),*(long *)($esp+8)

Your breakpoint should look something like the following:

This should log out messages like this when run against your application:

[UIApplication sharedApplication]
[UIApplication _isClassic]
[NSCFString getCString:maxLength:encoding:]
[UIApplication class]
[SLSMoleculeAppDelegate isSubclassOfClass:]
[SLSMoleculeAppDelegate initialize]

If you're wondering where I pulled the memory addresses, read this Phrack article on the Objective-C runtime internals. The memory addresses above will only work against the Simulator, so you might need to tweak this to run against applications on the iOS devices. Collin suggests the following modification in his answer to run this on a device:

printf "[%s %s]\n", (char *)object_getClassName($r0),$r1

Also, I think you'll see that logging out every method called in your application will overwhelm you with information. You might be able to use some conditions to filter this, but I don't know if this will help you to learn how your code executes.




回答2:


If you are using LLDB, you will need to use the following debugger commands. These were tested in Xcode 4.6.

Device:

expr -- (void) printf("[%s %s]\n", (char *)object_getClassName($r0),$r1)

Simulator:

expr -- (void) printf("[%s %s]\n", (char *)object_getClassName(*(long*)($esp+4)), *(long *)($esp+8))



回答3:


To trace the app code under Xcode 6 on device, I had to use the following debugger expression.

expr -- (void) printf("[%s %s]\n", (char *)object_getClassName($arg1),$arg2)



回答4:


Brad Larson's approach can be adapted to run on the device by using the debugger command:

printf "[%s %s]\n", (char *)object_getClassName($r0),$r1

More information can be found in the Technical Note here: technotes




回答5:


later xcode versions you need to call like that

expr -- (void)printf("[%s, %s]\n",(char *) object_getClassName(*(long*)($esp+4)), (char *) *(long *)($esp+8) )



回答6:


If you want to limit the output to just the messages sent to one class you can add a condition like this

(int)strcmp((char*)object_getClassName($r0), "NSString")==0




回答7:


A fellow developer taught me to add the same two log statements to each method. One as the first line, the other as the last line. I think he has a script that does this automatically for his projects, but the result is:

NSLog(@"<<< Entering %s >>>", __PRETTY_FUNCTION__);
NSLog(@"<<< Leaving %s >>>", __PRETTY_FUNCTION__);

At the console, this will spit out something like:

 <<< Entering -[MainListTableViewController viewDidLoad] >>>

Very helpful in tracking what is going on.




回答8:


If you want to log methods in the Simulator on 64 bit, use the following command instead:

expr -- (void) printf("[%s %s]\n", (char *)object_getClassName($rdi), (char *) $rsi)

Or if that doesn't work, log it this way:

The main idea is to use $rdi for the object (self), and $rsi for the selector.




回答9:


NSLog(@"%@", NSStringFromSelector(_cmd));

OR

NSLog(@"%s", __PRETTY_FUNCTION__);


来源:https://stackoverflow.com/questions/7270502/how-to-log-all-methods-used-in-ios-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!