承接上一篇,上一篇讲到可以在lldb调试中调用QuartzCore.framework里的CA::Render::Object::show方法来是观察CA::Render模块内的类的信息,但是在lldb控制台上却并没有任何输出信息,到底信息输出到哪里了呢,不知道最终目的去向,就等同功亏一篑。不着急(,话虽这样说),我们还是去看里面的反汇编代码,通过反汇编代码我们可以看到信息都是通过x_log函数输出的,里面又调用了x_logv函数。我要的答案就在这个x_logv函数里面,让我们来看看它的反汇编代码:

QuartzCore`x_logv:
0x107d10e54 <+>: pushq %rbp
0x107d10e55 <+>: movq %rsp, %rbp
0x107d10e58 <+>: pushq %r15
0x107d10e5a <+>: pushq %r14
0x107d10e5c <+>: pushq %r13
0x107d10e5e <+>: pushq %r12
0x107d10e60 <+>: pushq %rbx
0x107d10e61 <+>: subq $0x1018, %rsp
0x107d10e68 <+>: movq %rdx, %r14
0x107d10e6b <+>: movq %rsi, %rbx
0x107d10e6e <+>: movl %edi, %r15d
0x107d10e71 <+>: movq 0x36268(%rip), %r13 ; (void *)0x000000010bede070: __stack_chk_guard
0x107d10e78 <+>: movq (%r13), %r13
0x107d10e7c <+>: movq %r13, -0x30(%rbp)
0x107d10e80 <+>: movq $0x0, -0x1038(%rbp)
0x107d10e8b <+>: cmpq $-0x1, 0x35c4d(%rip) ; x_log_stream_slot + 7
0x107d10e93 <+>: jne 0x107d10ff1 ; <+413>
0x107d10e99 <+>: leal -0x1(%r15), %eax
0x107d10e9d <+>: cmpl $0x1, %eax
0x107d10ea0 <+>: ja 0x107d10ee4 ; <+144>
0x107d10ea2 <+>: movb 0x35c18(%rip), %al ; x_log_html
0x107d10ea8 <+>: testb %al, %al
0x107d10eaa <+>: je 0x107d10ee4 ; <+144>
0x107d10eac <+>: cmpl $0x2, %r15d
0x107d10eb0 <+>: leaq 0x20cd8(%rip), %rax ; "err"
0x107d10eb7 <+>: leaq 0x20cd5(%rip), %rdx ; "warn"
0x107d10ebe <+>: cmoveq %rax, %rdx
0x107d10ec2 <+>: leaq 0x20ccf(%rip), %rsi ; "<span class="%s">%s</span>"
0x107d10ec9 <+>: leaq -0x1038(%rbp), %rdi
0x107d10ed0 <+>: xorl %eax, %eax
0x107d10ed2 <+>: movq %rbx, %rcx
0x107d10ed5 <+>: callq 0x107d13bd8 ; symbol stub for: asprintf
0x107d10eda <+>: testl %eax, %eax
0x107d10edc <+>: cmovnsq -0x1038(%rbp), %rbx
0x107d10ee4 <+>: movq 0x35bed(%rip), %rdi ; x_log_stream_slot
0x107d10eeb <+>: testq %rdi, %rdi
0x107d10eee <+>: je 0x107d10f2e ; <+218>
0x107d10ef0 <+>: callq 0x107d13e96 ; symbol stub for: pthread_getspecific
0x107d10ef5 <+>: movq %rax, %r12
0x107d10ef8 <+>: testq %r12, %r12
0x107d10efb <+>: je 0x107d10f2e ; <+218>
0x107d10efd <+>: leaq -0x1030(%rbp), %r15
0x107d10f04 <+>: movl $0x1000, %esi
0x107d10f09 <+>: xorl %edx, %edx
0x107d10f0b <+>: movl $0x1000, %ecx
0x107d10f10 <+>: movq %r15, %rdi
0x107d10f13 <+>: movq %rbx, %r8
0x107d10f16 <+>: movq %r14, %r9
0x107d10f19 <+>: callq 0x107d13bae ; symbol stub for: __vsnprintf_chk
0x107d10f1e <+>: cmpl $0xfff, %eax
0x107d10f23 <+>: jg 0x107d10f64 ; <+272>
0x107d10f25 <+>: movq %r15, -0x1040(%rbp)
0x107d10f2c <+>: jmp 0x107d10f76 ; <+290>
0x107d10f2e <+>: movq 0x35b83(%rip), %rax ; x_log_function
0x107d10f35 <+>: testq %rax, %rax
0x107d10f38 <+>: je 0x107d10f4b ; <+247>
0x107d10f3a <+>: movq 0x35b87(%rip), %rdx ; x_log_function_info
0x107d10f41 <+>: movq %rbx, %rdi
0x107d10f44 <+>: movq %r14, %rsi
0x107d10f47 <+>: callq *%rax
0x107d10f49 <+>: jmp 0x107d10fc8 ; <+372>
0x107d10f4b <+>: movq 0x35b5e(%rip), %rdi ; x_log_file_handle
0x107d10f52 <+>: testq %rdi, %rdi
0x107d10f55 <+>: je 0x107d10fa0 ; <+332>
0x107d10f57 <+>: movq %rbx, %rsi
0x107d10f5a <+>: movq %r14, %rdx
0x107d10f5d <+>: callq 0x107d13f98 ; symbol stub for: vfprintf
0x107d10f62 <+>: jmp 0x107d10fc8 ; <+372>
0x107d10f64 <+>: leaq -0x1040(%rbp), %rdi
0x107d10f6b <+>: movq %rbx, %rsi
0x107d10f6e <+>: movq %r14, %rdx
0x107d10f71 <+>: callq 0x107d13f92 ; symbol stub for: vasprintf
0x107d10f76 <+>: testl %eax, %eax
0x107d10f78 <+>: jle 0x107d10f8d ; <+313>
0x107d10f7a <+>: movq (%r12), %rdi
0x107d10f7e <+>: movslq %eax, %rdx
0x107d10f81 <+>: leaq -0x1030(%rbp), %rsi
0x107d10f88 <+>: callq 0x107d12f64 ; x_stream_write
0x107d10f8d <+>: movq -0x1040(%rbp), %rdi
0x107d10f94 <+>: cmpq %r15, %rdi
0x107d10f97 <+>: je 0x107d10fc8 ; <+372>
0x107d10f99 <+>: callq 0x107d13d10 ; symbol stub for: free
0x107d10f9e <+>: jmp 0x107d10fc8 ; <+372>
0x107d10fa0 <+>: cmpl $0x1, %r15d
0x107d10fa4 <+>: setne %al
0x107d10fa7 <+>: movzbl %al, %eax
0x107d10faa <+>: orl $0x4, %eax
0x107d10fad <+>: cmpl $0x2, %r15d
0x107d10fb1 <+>: movl $0x3, %edx
0x107d10fb6 <+>: cmovnel %eax, %edx
0x107d10fb9 <+>: xorl %edi, %edi
0x107d10fbb <+>: xorl %esi, %esi
0x107d10fbd <+>: movq %rbx, %rcx
0x107d10fc0 <+>: movq %r14, %r8
0x107d10fc3 <+>: callq 0x107d13bd2 ; symbol stub for: asl_vlog
0x107d10fc8 <+>: movq -0x1038(%rbp), %rdi
0x107d10fcf <+>: testq %rdi, %rdi
0x107d10fd2 <+>: je 0x107d10fd9 ; <+389>
0x107d10fd4 <+>: callq 0x107d13d10 ; symbol stub for: free
0x107d10fd9 <+>: cmpq -0x30(%rbp), %r13
0x107d10fdd <+>: jne 0x107d1100b ; <+439>
0x107d10fdf <+>: addq $0x1018, %rsp
0x107d10fe6 <+>: popq %rbx
0x107d10fe7 <+>: popq %r12
0x107d10fe9 <+>: popq %r13
0x107d10feb <+>: popq %r14
0x107d10fed <+>: popq %r15
0x107d10fef <+>: popq %rbp
0x107d10ff0 <+>: retq
0x107d10ff1 <+>: leaq 0x35ae8(%rip), %rdi ; x_log_once
0x107d10ff8 <+>: leaq 0x11(%rip), %rdx ; x_log_init
0x107d10fff <+>: xorl %esi, %esi
0x107d11001 <+>: callq 0x107d13c62 ; symbol stub for: dispatch_once_f
0x107d11006 <+>: jmp 0x107d10e99 ; <+69>
0x107d1100b <+>: callq 0x107d13b9c ; symbol stub for: __stack_chk_fail

QuartzCore`x_logv:

相信也不会有人看的了,我下面贴上逆向出来的主要代码:

//
if ( == x_log_file_handle) { // 254 (0 == rdi)
// inline jmp 332
// 367 call
asl_vlog(, , (handle != 0x2) ? ((handle != 0x1) | 0x4) : 0x3, fmt, va_list);
// natural flow
goto _f372;
}
else { // 257 next
// 265 call
vfprintf(x_log_file_handle, fmt, va_list);
//
goto _f372;
} // 270 unreachable _f372: // from 330

可以看到这里有一个分支,分别用asl_vlog或vfprintf来输出信息。首先asl_vlog就是bsd系统的syslog系统日志函数,接着是vfprintf是我们熟悉的crt函数。当没有指定目标输出文件时,信息将输出到系统日志。好这就可以去系统日志控制台查找,但是系统日志var/logs里面的虽然有不少asl节点, 却权限问题访问不了的有很多,而且在可访问的节点里找不到我想要的信息。这也好办,可以使用vfprintf函数的输出,我们只要在lldb调试当中将打开的文件写入到全局变量x_log_file_handle,然后再使用上一篇介绍过的方法调用CA::Render::Layer::show方法。日志文件被写入了信息,这样我们就可以使用其自身的日志功能,查找收集一些内部的信息了。

在lldb调试中调用c++函数 - 如何使用QuartzCore里面的日志消息的更多相关文章

  1. 在lldb调试中调用c++函数

    在lldb调试时,调用oc对象的方法不足为奇,因为msgSend是有原型导出的,oc对象的方法都运行期绑定的,绑定信息都在objc_class中.只要在调试中[receiver sel]之类,lldb ...

  2. C++箴言:避免构造或析构函数中调用虚函数

    如果你已经从另外一种语言如C#或者Java转向了C++,你会觉得,避免在类的构造函数或者析构函数中调用虚函数这一原则有点违背直觉.但是在C++中,违反这个原则会给你带来难以预料的后果和无尽的烦恼. 正 ...

  3. 读书笔记 effective c++ Item 9 绝不要在构造函数或者析构函数中调用虚函数

    关于构造函数的一个违反直觉的行为 我会以重复标题开始:你不应该在构造或者析构的过程中调用虚函数,因为这些调用的结果会和你想的不一样.如果你同时是一个java或者c#程序员,那么请着重注意这个条款,因为 ...

  4. 【校招面试 之 C/C++】第10题 C++不在构造函数和析构函数中调用虚函数

    1.不要在构造函数中调用虚函数的原因 在概念上,构造函数的工作是为对象进行初始化.在构造函数完成之前,被构造的对象被认为“未完全生成”.当创建某个派生类的对象时,如果在它的基类的构造函数中调用虚函数, ...

  5. 【VS开发】MFC中调用C函数模块的解决方案

    [VS开发]MFC中调用C函数模块的解决方案 标签(空格分隔): [VS开发] 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:最近调试基于MFC的程序 ...

  6. C++构造与析构函数中调用虚函数的问题

    前些天想把以前写的内存池算法重写一遍,跨平台是第一目标,当时突发奇想,因为不愿意做成一大堆#if..#end,所以想利用C++的多态性,但是怎么让内存池完好退出却没想到自认为完美的方案.但是一个很偶然 ...

  7. EC笔记,第二部分:9.不在构造、析构函数中调用虚函数

    9.不在构造.析构函数中调用虚函数 1.在构造函数和析构函数中调用虚函数会产生什么结果呢? #; } 上述程序会产生什么样的输出呢? 你一定会以为会输出: cls2 make cls2 delete ...

  8. 关于在C#中构造函数中调用虚函数的问题

    在C#中如果存在类的继承关系,应避免在构造函数中调用虚函数.这是由于C#的运行机制造成的,原因如下: 新建一个类实例时,C#会先初始化该类(对类变量赋值,并将函数记在函数表中),然后再初始化父类.构造 ...

  9. 如何在C语言中调用Swift函数

    在Apple官方的<Using Swift with Cocoa and Objectgive-C>一书中详细地介绍了如何在Objective-C中使用Swift的类以及如何在Swift中 ...

随机推荐

  1. shell数组(四)

    [root@ipha-dev71- exercise_shell]# cat test.sh #!/bin/bash my_array=(a b c d) echo "第一个元素为:${my ...

  2. SpringBoot系列教程之Bean加载顺序之错误使用姿势辟谣

    在网上查询 Bean 的加载顺序时,看到了大量的文章中使用@Order注解的方式来控制 bean 的加载顺序,不知道写这些的博文的同学自己有没有实际的验证过,本文希望通过指出这些错误的使用姿势,让观文 ...

  3. 基于STM32F103和Cube的输入捕获例程

    1.开发环境 (1)Cube5.24 (2)Keil5 (3)STM32F103 2.Cube配置 Cube配置很简单,只要打开TIM4通道1的引脚,设置为输入捕获模式,在配置是高或低电平沿触发 TI ...

  4. JUC - ReentrantLock 的基本用法 以及 lock()、tryLock()、lockInterruptibly()的区别

    ReentrantLock 与 synchronized对比 最近有在阅读Java并发编程实战这本书,又看到了ReentrantLock和synchronized的对比,发现自己以前对于Renntra ...

  5. (六)添加adbmingling

    给环境变量Path添加adb命令路径,即adb.exe所在的目录 C:\Users\LIU Liang\AppData\Local\Android\Sdk\platform-tools

  6. Spring框架学习笔记(6)——阿里云服务器部署Spring Boot项目(jar包)

    最近接外包,需要部署服务器,便是参考了网上的几篇博文,成功在阿里云服务器成功部署了Spring Boot项目,特记下本篇笔记 Spring Boot项目打包 这里说一下部署的一些问题 1.mysql驱 ...

  7. 通过CSS3实现圆形头像显示

    很久没更新博客了,因为比较菜,也没什么能在上面分享的.作为新手,马上要毕业找工作了,最近又在重新学习web的一些知识,刚刚学到CSS3,跟大家分享一些比较有趣的知识.今天分享的是利用CSS实现圆形头像 ...

  8. ES6对象简洁语法

    对象(object)是 JavaScript 最重要的数据结构.ES6 对它进行了重大升级,本章介绍数据结构本身的改变及语法应用细节. 1.属性的简洁表示法 ◆ ES6 允许直接写入变量和函数,作为对 ...

  9. 利用AXI VDMA实现OV5640摄像头采集笔记(二)

    导读:摄像头采样图像数据后经过VDMA进入DDR,通过PS部分控制,经过三级缓存,将DDR中保持的图形数据通过VDMA发送出去.在FPGA的接收端口产生VID OUT时序驱动HDMI显示器显示图形. ...

  10. [开源] gnet: 一个轻量级且高性能的 Golang 网络库

    Github 主页 https://github.com/panjf2000/gnet 欢迎大家围观~~,目前还在持续更新,感兴趣的话可以 star 一下暗中观察哦. 简介 gnet 是一个基于 Ev ...