Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SMCallTrace 调用栈顺序问题 #19

Open
chipengliu opened this issue Aug 23, 2019 · 1 comment
Open

SMCallTrace 调用栈顺序问题 #19

chipengliu opened this issue Aug 23, 2019 · 1 comment

Comments

@chipengliu
Copy link

chipengliu commented Aug 23, 2019

问题1、拼接调用栈路径path顺序不正确

- (void)viewDidLoad {
    [super viewDidLoad];
    UIWebView *webview = [[UIWebView alloc] init];
    [self.view addSubview:webview];
    NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];
    NSURLRequest *req = [[NSURLRequest alloc] initWithURL:url];
    [webview loadRequest:req];
    webview.frame = self.view.bounds;

    [self testMethod1];
}

- (void)testMethod1 {
    NSString *imgName = [NSString stringWithFormat:@"guide_1"];
    NSString *path = [[NSBundle mainBundle] pathForResource:imgName ofType:@"png"];
    UIImage *image = [UIImage imageWithContentsOfFile:path];
    self.view.backgroundColor = [UIColor colorWithPatternImage:image];
    
    [self testMethod2];
}

- (void)testMethod2 {
    [self testMethod3];
}

- (void)testMethod3 {
    NSString *imgName = [NSString stringWithFormat:@"guide_3"];
    NSString *path = [[NSBundle mainBundle] pathForResource:imgName ofType:@"png"];
    UIImage *image = [UIImage imageWithContentsOfFile:path];
    self.view.backgroundColor = [UIColor colorWithPatternImage:image];
    
    UIGraphicsBeginImageContext(self.view.frame.size);
    [image drawInRect:self.view.bounds];
    image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    self.view.backgroundColor = [UIColor colorWithPatternImage:image];
}

这里UIWebView某些回调方法是通过异步回到主线程执行,看起来多线程打印的调用栈路径是错误的,打印出来的信息是:

 0| +[UIWebView alloc]
 path[UIWebView alloc]
 0| -[UIWebView init]
 path[UIWebView init]
 0| -[ViewController testMethod1]
 path[ViewController testMethod1]
 1|   -[ViewController testMethod2]
 path[ViewController testMethod1] - [ViewController testMethod2]
 2|     -[ViewController testMethod3]
 path[ViewController testMethod1] - [ViewController testMethod2] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[ViewController testMethod1] - [ViewController testMethod2] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   +[UIImage imageWithContentsOfFile:]
 path[ViewController testMethod1] - [UIImage imageWithContentsOfFile:]
 0| -[_WebSafeForwarder webView:decidePolicyForNavigationAction:request:frame:decisionListener:]
 path[_WebSafeForwarder webView:decidePolicyForNavigationAction:request:frame:decisionListener:]
 1|   -[UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:]
 path[_WebSafeForwarder webView:decidePolicyForNavigationAction:request:frame:decisionListener:] - [UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:]
 2|     -[ViewController testMethod3]
 path[_WebSafeForwarder webView:decidePolicyForNavigationAction:request:frame:decisionListener:] - [UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[_WebSafeForwarder webView:decidePolicyForNavigationAction:request:frame:decisionListener:] - [UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   -[ViewController testMethod2]
 path[_WebSafeForwarder webView:decidePolicyForNavigationAction:request:frame:decisionListener:] - [ViewController testMethod2]
 2|     -[ViewController testMethod3]
 path[_WebSafeForwarder webView:decidePolicyForNavigationAction:request:frame:decisionListener:] - [ViewController testMethod2] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[_WebSafeForwarder webView:decidePolicyForNavigationAction:request:frame:decisionListener:] - [ViewController testMethod2] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   +[UIImage imageWithContentsOfFile:]
 path[_WebSafeForwarder webView:decidePolicyForNavigationAction:request:frame:decisionListener:] - [UIImage imageWithContentsOfFile:]
 0| -[_WebSafeForwarder webView:decidePolicyForMIMEType:request:frame:decisionListener:]
 path[_WebSafeForwarder webView:decidePolicyForMIMEType:request:frame:decisionListener:]
 1|   -[UIWebViewWebViewDelegate webView:decidePolicyForMIMEType:request:frame:decisionListener:]
 path[_WebSafeForwarder webView:decidePolicyForMIMEType:request:frame:decisionListener:] - [UIWebViewWebViewDelegate webView:decidePolicyForMIMEType:request:frame:decisionListener:]
 2|     -[ViewController testMethod3]
 path[_WebSafeForwarder webView:decidePolicyForMIMEType:request:frame:decisionListener:] - [UIWebViewWebViewDelegate webView:decidePolicyForMIMEType:request:frame:decisionListener:] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[_WebSafeForwarder webView:decidePolicyForMIMEType:request:frame:decisionListener:] - [UIWebViewWebViewDelegate webView:decidePolicyForMIMEType:request:frame:decisionListener:] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   -[UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:]
 path[_WebSafeForwarder webView:decidePolicyForMIMEType:request:frame:decisionListener:] - [UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:]
 2|     -[ViewController testMethod3]
 path[_WebSafeForwarder webView:decidePolicyForMIMEType:request:frame:decisionListener:] - [UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[_WebSafeForwarder webView:decidePolicyForMIMEType:request:frame:decisionListener:] - [UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   -[ViewController testMethod2]
 path[_WebSafeForwarder webView:decidePolicyForMIMEType:request:frame:decisionListener:] - [ViewController testMethod2]
 2|     -[ViewController testMethod3]
 path[_WebSafeForwarder webView:decidePolicyForMIMEType:request:frame:decisionListener:] - [ViewController testMethod2] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[_WebSafeForwarder webView:decidePolicyForMIMEType:request:frame:decisionListener:] - [ViewController testMethod2] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   +[UIImage imageWithContentsOfFile:]
 path[_WebSafeForwarder webView:decidePolicyForMIMEType:request:frame:decisionListener:] - [UIImage imageWithContentsOfFile:]
 0| -[_WebSafeForwarder webView:didCommitLoadForFrame:]
 path[_WebSafeForwarder webView:didCommitLoadForFrame:]
 1|   -[UIWebBrowserView webView:didCommitLoadForFrame:]
 path[_WebSafeForwarder webView:didCommitLoadForFrame:] - [UIWebBrowserView webView:didCommitLoadForFrame:]
 2|     -[ViewController testMethod3]
 path[_WebSafeForwarder webView:didCommitLoadForFrame:] - [UIWebBrowserView webView:didCommitLoadForFrame:] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[_WebSafeForwarder webView:didCommitLoadForFrame:] - [UIWebBrowserView webView:didCommitLoadForFrame:] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   -[UIWebViewWebViewDelegate webView:decidePolicyForMIMEType:request:frame:decisionListener:]
 path[_WebSafeForwarder webView:didCommitLoadForFrame:] - [UIWebViewWebViewDelegate webView:decidePolicyForMIMEType:request:frame:decisionListener:]
 2|     -[ViewController testMethod3]
 path[_WebSafeForwarder webView:didCommitLoadForFrame:] - [UIWebViewWebViewDelegate webView:decidePolicyForMIMEType:request:frame:decisionListener:] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[_WebSafeForwarder webView:didCommitLoadForFrame:] - [UIWebViewWebViewDelegate webView:decidePolicyForMIMEType:request:frame:decisionListener:] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   -[UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:]
 path[_WebSafeForwarder webView:didCommitLoadForFrame:] - [UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:]
 2|     -[ViewController testMethod3]
 path[_WebSafeForwarder webView:didCommitLoadForFrame:] - [UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[_WebSafeForwarder webView:didCommitLoadForFrame:] - [UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   -[ViewController testMethod2]
 path[_WebSafeForwarder webView:didCommitLoadForFrame:] - [ViewController testMethod2]
 2|     -[ViewController testMethod3]
 path[_WebSafeForwarder webView:didCommitLoadForFrame:] - [ViewController testMethod2] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[_WebSafeForwarder webView:didCommitLoadForFrame:] - [ViewController testMethod2] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   +[UIImage imageWithContentsOfFile:]
 path[_WebSafeForwarder webView:didCommitLoadForFrame:] - [UIImage imageWithContentsOfFile:]
 0| -[_WebSafeForwarder webView:didFinishLoadForFrame:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:]
 1|   -[UIWebBrowserView webView:didFinishLoadForFrame:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebBrowserView webView:didFinishLoadForFrame:]
 2|     -[ViewController testMethod3]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebBrowserView webView:didFinishLoadForFrame:] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebBrowserView webView:didFinishLoadForFrame:] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   -[UIWebBrowserView webView:didCommitLoadForFrame:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebBrowserView webView:didCommitLoadForFrame:]
 2|     -[ViewController testMethod3]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebBrowserView webView:didCommitLoadForFrame:] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebBrowserView webView:didCommitLoadForFrame:] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   -[UIWebViewWebViewDelegate webView:decidePolicyForMIMEType:request:frame:decisionListener:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebViewWebViewDelegate webView:decidePolicyForMIMEType:request:frame:decisionListener:]
 2|     -[ViewController testMethod3]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebViewWebViewDelegate webView:decidePolicyForMIMEType:request:frame:decisionListener:] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebViewWebViewDelegate webView:decidePolicyForMIMEType:request:frame:decisionListener:] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   -[UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:]
 2|     -[ViewController testMethod3]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   -[ViewController testMethod2]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [ViewController testMethod2]
 2|     -[ViewController testMethod3]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [ViewController testMethod2] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [ViewController testMethod2] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   +[UIImage imageWithContentsOfFile:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIImage imageWithContentsOfFile:]
 0| -[_WebSafeForwarder webView:didFinishLoadForFrame:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:]
 1|   -[UIWebViewWebViewDelegate webView:didFinishLoadForFrame:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebViewWebViewDelegate webView:didFinishLoadForFrame:]
 2|     -[ViewController testMethod3]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebViewWebViewDelegate webView:didFinishLoadForFrame:] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebViewWebViewDelegate webView:didFinishLoadForFrame:] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   -[UIWebBrowserView webView:didFinishLoadForFrame:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebBrowserView webView:didFinishLoadForFrame:]
 2|     -[ViewController testMethod3]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebBrowserView webView:didFinishLoadForFrame:] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebBrowserView webView:didFinishLoadForFrame:] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   -[UIWebBrowserView webView:didCommitLoadForFrame:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebBrowserView webView:didCommitLoadForFrame:]
 2|     -[ViewController testMethod3]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebBrowserView webView:didCommitLoadForFrame:] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebBrowserView webView:didCommitLoadForFrame:] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   -[UIWebViewWebViewDelegate webView:decidePolicyForMIMEType:request:frame:decisionListener:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebViewWebViewDelegate webView:decidePolicyForMIMEType:request:frame:decisionListener:]
 2|     -[ViewController testMethod3]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebViewWebViewDelegate webView:decidePolicyForMIMEType:request:frame:decisionListener:] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebViewWebViewDelegate webView:decidePolicyForMIMEType:request:frame:decisionListener:] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   -[UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:]
 2|     -[ViewController testMethod3]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   -[ViewController testMethod2]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [ViewController testMethod2]
 2|     -[ViewController testMethod3]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [ViewController testMethod2] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [ViewController testMethod2] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   +[UIImage imageWithContentsOfFile:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIImage imageWithContentsOfFile:]

如果在loadRecords方法第二层循环加上break,看起才是正常的

    for (NSUInteger i = 0; i < count; i++) {
        SMCallTraceTimeCostModel *model = arr[i];
        if (model.callDepth > 0) {
            [arr removeObjectAtIndex:i];
            //Todo:不需要循环,直接设置下一个,然后判断好边界就行
            for (NSUInteger j = i; j < count - 1; j++) {
                //下一个深度小的话就开始将后面的递归的往 sub array 里添加
                if (arr[j].callDepth + 1 == model.callDepth) {
                    NSMutableArray *sub = (NSMutableArray *)arr[j].subCosts;
                    if (!sub) {
                        sub = [NSMutableArray new];
                        arr[j].subCosts = sub;
                    }
                    [sub insertObject:model atIndex:0];
                    break;//->fix 找到父节点结束遍历
                }
            }
            i--;
            count--;
        }
    }

加了break 之后输出

 0| +[UIWebView alloc]
 path[UIWebView alloc]
 0| -[UIWebView init]
 path[UIWebView init]
 0| -[ViewController testMethod1]
 path[ViewController testMethod1]
 1|   -[ViewController testMethod2]
 path[ViewController testMethod1] - [ViewController testMethod2]
 2|     -[ViewController testMethod3]
 path[ViewController testMethod1] - [ViewController testMethod2] - [ViewController testMethod3]
 3|       -[UIImage drawInRect:]
 path[ViewController testMethod1] - [ViewController testMethod2] - [ViewController testMethod3] - [UIImage drawInRect:]
 1|   +[UIImage imageWithContentsOfFile:]
 path[ViewController testMethod1] - [UIImage imageWithContentsOfFile:]
 0| -[_WebSafeForwarder webView:decidePolicyForNavigationAction:request:frame:decisionListener:]
 path[_WebSafeForwarder webView:decidePolicyForNavigationAction:request:frame:decisionListener:]
 1|   -[UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:]
 path[_WebSafeForwarder webView:decidePolicyForNavigationAction:request:frame:decisionListener:] - [UIWebViewWebViewDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:]
 0| -[_WebSafeForwarder webView:decidePolicyForMIMEType:request:frame:decisionListener:]
 path[_WebSafeForwarder webView:decidePolicyForMIMEType:request:frame:decisionListener:]
 1|   -[UIWebViewWebViewDelegate webView:decidePolicyForMIMEType:request:frame:decisionListener:]
 path[_WebSafeForwarder webView:decidePolicyForMIMEType:request:frame:decisionListener:] - [UIWebViewWebViewDelegate webView:decidePolicyForMIMEType:request:frame:decisionListener:]
 0| -[_WebSafeForwarder webView:didCommitLoadForFrame:]
 path[_WebSafeForwarder webView:didCommitLoadForFrame:]
 1|   -[UIWebBrowserView webView:didCommitLoadForFrame:]
 path[_WebSafeForwarder webView:didCommitLoadForFrame:] - [UIWebBrowserView webView:didCommitLoadForFrame:]
 0| -[_WebSafeForwarder webView:didFinishLoadForFrame:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:]
 1|   -[UIWebViewWebViewDelegate webView:didFinishLoadForFrame:]
 path[_WebSafeForwarder webView:didFinishLoadForFrame:] - [UIWebViewWebViewDelegate webView:didFinishLoadForFrame:]

问题2、debug由于hook objc_msgSend 导致 堆栈信息不全

在同一行代码用bt命令打印堆栈
hook前
hook前

hook后
hook后


问题3、无法检测viewDidLoad, viewWillAppear 等一些UIKit的方法

目前发现 UIViewController、UIResponder 等一些方法是无法记录的

@isdotjim
Copy link

搭个车...
想邀请Repo作者来w3c.group创建项目的对应小组。w3c.group是类似知识星球的社群工具,小组可设置为付费且有赞助功能,同时也是一个区块链主导的创作者社区。这是相关介绍:
http://t.cn/Ai1vLcCU
http://t.cn/Ai1vLcCG
http://t.cn/Ai1vLcCA

@erduoniba
Copy link

问题一:路径问题应该是调用链路错误导致,可以参考下面的提交
#30
问题二:不太好确认是什么关系,但是我理解不影响使用,毕竟这个工具是用于开发定位问题,而不是代入线上;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants