GithubHelp home page GithubHelp logo

omxcodec / ocmethodtrace Goto Github PK

View Code? Open in Web Editor NEW
249.0 9.0 35.0 108 KB

Trace Any Objective-C Method Calls

License: Apache License 2.0

Objective-C 61.60% Assembly 29.99% Objective-C++ 7.76% C 0.65%
objective-c trace-method methodswizzling hook forwardinvocation nsinvocation

ocmethodtrace's Introduction

OCMethodTrace - Trace Any Objective-C Method Calls

跟踪打印Objective-C任何实例(类)方法

功能:

  1. 支持任意OC实例(类)方法的跟踪打印
  2. 支持多架构(arm32,arm64,i386,x86_64)
  3. 支持跟踪父类和子类相同的方法
  4. 支持各种灵活配置,包括方法黑白名单等

配置说明:

全局配置:

LogLevel:Trace日志级别,对应MDTraceLogLevel,必须定义,默认值:0

0:MDTraceLogLeveError,错误级别
1:MDTraceLogLeveDebug,调试级别

LogWhen:Trace日志输出时机,对应MDTraceLogWhen,必须定义,默认值:0

0:MDTraceLogWhenStartup ,启动即输出日志
1:MDTraceLogWhenVolume ,根据音量键控制输出日志(增加音量:输出日志;降低音量:关闭日志;默认时关闭日志)
2:MDTraceLogWhenRegexString ,输出日志包含匹配字符串才输出日志

LogRegexString:日志正则匹配字符串,仅当logWhen=MDTraceLogWhenRegexString有效。日志包含指定正则字符串才输出日志

TraceFlag:Trace控制位(尽量在该处扩展),对应MDTraceFlag,全局必须定义,默认值:0x02,指定类可选定义,默认值:0x00

0x01:MDTraceFlagDoesNotUseDescription,跳过调用对象description方法,避免不正规的description实现导致递归
0x02:MDTraceFlagDumpClassListInfo,打印类列表信息,便于调试
0x04:MDTraceFlagDumpClassMethod,打印某个类的方法(不包括父类方法),便于调试
0x08:MDTraceFlagDumpSuperClassMethod,打印某个类的父类方法(包括递归父类的方法),便于调试

TraceObject:Trace对象,对应TraceObject,必须定义,默认值:1

0:MDTraceObjectNone,屏蔽trace所有类
1:MDTraceObjectCoreClass,trace引擎指定类的方法(仅测试验证使用),仅需要考虑CORE_CLASS_LIST
2:MDTraceObjectUserClass,trace用户指定类的方法,需要考虑USER_CLASS_LIST + "USER_CLASS_LIST和CORE_CLASS_LIST交集"
3:MDTraceObjectRegexClass,trace用户指定类 + 正则匹配类的方法,需要考虑USER_CLASS_LIST + "USER_CLASS_LIST和CORE_CLASS_LIST交集" + "匹配ClassRegexString的CLASS_LIST和CORE_CLASS_LIST交集"

MDTraceObjectUserClass和MDTraceObjectRegexClass的区别:
* MDTraceObjectUserClass:在考虑USER_CLASS_LIST指定的类的时候,如果USER_CLASS_LIST和CORE_CLASS_LIST存在部分交集,交集对应的类需要合并,合并算法详见:+[MDTraceClassInfo mergeInfoWithCoreInfo:userInfo:userInfo:]
* MDTraceObjectRegexClass:在考虑MDTraceObjectUserClass的基础上,再考虑ClassRegexString正则匹配的类。

处理TraceObject的详细算法见:-[ MDMethodTrace parseClassListInfo],算法内部注意优先级顺序:core > user > regex

指定类配置:

USER_CLASS_LIST:用户指定类列表,必须定义

TraceMode: Trace模式,对应MDTraceMode,可选定义,默认值:1
    0:MDTraceModeOff,屏蔽trace方法
    1:MDTraceModeAll,trace所有方法
    2:MDTraceModeIncludeWhiteList,trace包含"白名单方法列表"的方法
    3:MDTraceModeExcludeBlackList,trace排除"黑名单方法列表"的方法
TraceFlag:定义同全局配置,但是粒度更小,属于某个类范围内,可选定义,默认值:0x00
MethodWhiteList:白名单方法列表,可选定义,但MDTraceModeIncludeWhiteList时必须定义
MethodBlackList:黑名单方法列表,可选定义,但MDTraceModeExcludeBlackList时必须定义

跟踪某些类的时候,该类的某些方法有可能会导致app崩溃。这时候,你可以通过多次的试验,找出导致崩溃的方法,使用黑名单模式,然后把这些异常方法放在黑名单方法列表中。当然,如果你并不需要跟踪该类全部的方法的话,也可以使用白名单模式。

CORE_CLASS_LIST:引擎指定类列表,必须定义

TraceMode:定义同USER_CLASS_LIST的TraceMode,但是仅支持MDTraceModeOff和MDTraceModeExcludeBlackList
TraceFlag:定义同全局配置,但是粒度更小,属于某个类范围内,可选定义,默认值:0x00
MethodBlackList:黑名单方法列表,可选定义,但MDTraceModeExcludeBlackList时必须定义

ClassRegexString:类正则匹配字符串,仅TraceObject=MDTraceObjectRegexClass有效

每个匹配的类使用默认类配置(可以理解成一个默认的User类)。使用场景:在不确定trace哪些类的情况下,批量trace一些有规律命名方式的类,匹配字符串如:“Notification|^CM|(F|f)igCaptureSource”

USER_CLASS_LIST和CORE_CLASS_LIST的关系:

* CORE_CLASS_LIST:存在的意义在于,OCMethodTrace框架(引擎)内部也需要调用一些OC类方法,为了保证整个框架可以跑起来,避免trace到框架内部使用到的类导致的打印递归循环,所以,需排除这些指定类的全部方法或者部分方法。
* USER_CLASS_LIST:用户自己指定的类,可以任意发挥。但是如果CORE_CLASS_LIST有相同的类,会优先CORE_CLASS_LIST中的配置。合并算法详见"+[MDTraceClassInfo mergeInfoWithCoreInfo:userInfo:userInfo:]"

技术要点:

支持跟踪父类和子类相同的方法

SatanWoo提出了一个方法(见感谢2),使用“runtime的消息转发机制+跳板原理(桥)”实现,流程:
每个方法置换到不同的IMP桥上 -> 从桥上反推出当前的调用关系(class和selector)-> 构造一个中间态新名字 -> forwardingTargetForSelector(self, 中间态新名字) 。
但是SatanWoo的demo(见感谢3)有两个比较大的缺陷:
* 仅支持arm64平台,不支持多架构;
* 仅支持实例方法,不支持类方法。
为此我做了一些改进,如下:
* 支持多架构:参考objc4(见感谢4)的objc-block-trampolines.m,编写了一个通用的跳板实现,其中通过汇编支持多架构。
* 支持类方法:NSObject (OCMethodTrace)需hook类方法"+[NSObject forwardingTargetForSelector:]"

Trace输出无限循环递归的特殊处理

递归调用都发生在"-[OCMethodTrace omt_forwardInvocation:]"函数内部,有两个地方:
* 对象调用自身的description导致的无限递归:为了打印对象的描述,需要调用对象的description方法,而该方法内部很可能会调用对象的其它内部方法,继而递归又调用"-[OCMethodTrace omt_forwardInvocation:]",于是无限循环。当前解决的方法是:在"-[OCMethodTrace omt_forwardInvocation:]"开始处通过遍历函数堆栈链查找"OMTBlockRunBeforeSelector","OMTBlockRunAfterSelector"和"OMTDescriptionWithTargetSelector"这几个方法,可以知道是否存在递归,发现递归就不要再调用runBefore和runAfter回调即可。缺点:遍历函数堆栈链的方法实在不优雅,而且性能也受影响,需要优化!
* OCMethodTrace框架使用到的基础类导致的无限递归:比如"-[OCMethodTrace omt_forwardInvocation:]"函数范围内用到一些类:如NSDate,NSString或者runBefore或runAfter回调用到的方法等,一旦他们也被trace,也会导致循环递归。解决的思路是:把这些类放在黑名单里,不再trace。当然还有降低循环递归的方式是,内部实现尽量使用C或者C++实现。

TODO:

  1. 通过遍历堆栈链,判断是否存在循环递归调用的算法性能太差,需优化。
  2. 开启全局dump类方法(MDTraceFlagDumpClassMethod)容易导致异常,不建议开启。

感谢:

  1. https://github.com/qhd/ANYMethodLog
  2. https://satanwoo.github.io/2017/09/24/mainthreadchecker1
  3. https://github.com/SatanWoo/MainThreadChecker.git
  4. https://opensource.apple.com/tarballs/objc4/objc4-723.tar.gz

欢迎提Issues和Pull requests,如有问题,可以联系 Michael Chen ([email protected])

ocmethodtrace's People

Contributors

omxcodec avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ocmethodtrace's Issues

unrecognized selector sent to instance

image

image

您好,请问一下,我根据您的README配置的plist,hook某个类的所有方法,或者hook类的白名单方法,都会崩溃。能帮我看一下是哪配置的有问题吗?
微信版本 7.0.4
系统版本 iOS 12.1.4

Command CompileC failed with a nonzero exit code

你好:
我的IDE是xcode10.1,在模拟器环境下,直接运行你的demo可以成功跑起来,但是拉到我的项目里时,却会在编译a2a3-selectortramps-x86_64.s 时就会报一个Command CompileC failed with a nonzero exit code

查了半天没查出来是啥原因,请问你知道是怎么回事吗?

在IOS11以及IOS12上,会发生崩溃

-[WCAccountLoginControlLogic __OMTMessageTemp_WCBaseControlLogic->init]: unrecognized selector sent to instance 0x1c0a843d0'

目标APP为微信,换成IOS10系统的话,可以正常

无法正常打印

截圖 2020-11-24 16 24 30

已按照使用说明去设置打印
但无法打印出任何东西!!
有解决方式吗?还是那边有设置错误?

打扰下。我这样子配置一直不打印任何日志。

[
截屏2024-03-06 09 57 59
MethodTrace] logLevel: 1: logWhen: 0 traceFlag: 2 traceObject: 2(用户类)
[MethodTrace] Dump 用户类 class list info:
[MethodTrace] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[MethodTrace] ClassList[00000]: <MDTraceClassInfo: 0x281ddac10 name: BaseMsgContentViewController source: 1 mode: 0 flag: 1 methodList: (
)>
[MethodTrace] ClassList[00001]: <MDTraceClassInfo: 0x281ddac40 name: VoIPCallerViewController source: 1 mode: 1 flag: 0 methodList: (
)>
[MethodTrace] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[MethodTrace]
[MethodTrace] ////////////////////////////////////////////////////////////////////////////////
[MethodTrace]
[MethodTrace] ClassList[00000]: BaseMsgContentViewController
[MethodTrace] ClassList[00001]: VoIPCallerViewController
[MethodTrace]
[MethodTrace] ////////////////////////////////////////////////////////////////////////////////
[MethodTrace]

请问怎么配置打印某个类的方法呢

如:
USER_CLASS_LIST
QLVideoDetailViewController
TraceMode 3
TraceFlag 4
MethodBlackList
MethodWhiteList
我只想打印某个类的所有发放,但是很多情况不管怎么配置都会crash,还是之间的打印方法日志比较简单,这个又繁琐,又不知道怎么配置

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.