在lldb调试中调用c++函数 - 如何使用QuartzCore里面的日志消息
承接上一篇,上一篇讲到可以在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里面的日志消息的更多相关文章
- 在lldb调试中调用c++函数
在lldb调试时,调用oc对象的方法不足为奇,因为msgSend是有原型导出的,oc对象的方法都运行期绑定的,绑定信息都在objc_class中.只要在调试中[receiver sel]之类,lldb ...
- C++箴言:避免构造或析构函数中调用虚函数
如果你已经从另外一种语言如C#或者Java转向了C++,你会觉得,避免在类的构造函数或者析构函数中调用虚函数这一原则有点违背直觉.但是在C++中,违反这个原则会给你带来难以预料的后果和无尽的烦恼. 正 ...
- 读书笔记 effective c++ Item 9 绝不要在构造函数或者析构函数中调用虚函数
关于构造函数的一个违反直觉的行为 我会以重复标题开始:你不应该在构造或者析构的过程中调用虚函数,因为这些调用的结果会和你想的不一样.如果你同时是一个java或者c#程序员,那么请着重注意这个条款,因为 ...
- 【校招面试 之 C/C++】第10题 C++不在构造函数和析构函数中调用虚函数
1.不要在构造函数中调用虚函数的原因 在概念上,构造函数的工作是为对象进行初始化.在构造函数完成之前,被构造的对象被认为“未完全生成”.当创建某个派生类的对象时,如果在它的基类的构造函数中调用虚函数, ...
- 【VS开发】MFC中调用C函数模块的解决方案
[VS开发]MFC中调用C函数模块的解决方案 标签(空格分隔): [VS开发] 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:最近调试基于MFC的程序 ...
- C++构造与析构函数中调用虚函数的问题
前些天想把以前写的内存池算法重写一遍,跨平台是第一目标,当时突发奇想,因为不愿意做成一大堆#if..#end,所以想利用C++的多态性,但是怎么让内存池完好退出却没想到自认为完美的方案.但是一个很偶然 ...
- EC笔记,第二部分:9.不在构造、析构函数中调用虚函数
9.不在构造.析构函数中调用虚函数 1.在构造函数和析构函数中调用虚函数会产生什么结果呢? #; } 上述程序会产生什么样的输出呢? 你一定会以为会输出: cls2 make cls2 delete ...
- 关于在C#中构造函数中调用虚函数的问题
在C#中如果存在类的继承关系,应避免在构造函数中调用虚函数.这是由于C#的运行机制造成的,原因如下: 新建一个类实例时,C#会先初始化该类(对类变量赋值,并将函数记在函数表中),然后再初始化父类.构造 ...
- 如何在C语言中调用Swift函数
在Apple官方的<Using Swift with Cocoa and Objectgive-C>一书中详细地介绍了如何在Objective-C中使用Swift的类以及如何在Swift中 ...
随机推荐
- Flink实战| Flink+Redis实时防刷接口作弊
随着人口红利的慢慢削减,互联网产品的厮杀愈加激烈,大家开始看好下沉市场的潜力,拼多多,趣头条等厂商通过拉新奖励,购物优惠等政策率先抢占用户,壮大起来.其他各厂商也紧随其后,纷纷推出自己产品的极速版,如 ...
- python学习-文件I/O
12.2使用os.path操作目录 # os.path_test.py import os import time print(os.path.abspath("abc.txt") ...
- Java_条件控制与循环控制
条件控制语句: 1. if-else语句 if(条件1){ 代码块1; }else if(条件2){ 代码块2; }else{ 代码块3; } 2. switch语句 switch(变 ...
- 腾讯云上面部署PHP运行环境
现在云服务器已经很普及了,其价格.安全优势等成为不少开发者的首选.本人由于兴趣爱好,从朋友那边借了一个过来玩了两天,下面就分享整个部署流程吧. 1. 先到腾讯云官网购买服务器,这边就不演示.很简单,跟 ...
- css四种基本选择器
css选择器是什么? 要使用css对HTML页面中的元素实现一对一,一对多或者多对一的控制,这就需要用到CSS选择器. HTML页面中的元素就是通过CSS选择器进行控制的. CSS选择器:就是指定CS ...
- SpringBoot整合Redis在可视化工具乱码问题,以及常用的api
pom依赖: <parent> <groupId>org.springframework.boot</groupId> <artifactId>spr ...
- git log 附加命令归纳
git查看历史记录的时候查看每次提交的内容差异: git log -p git限制显示的条数 : git log -p -2 [-2] git简单显示每次提交做了哪些改动: git log --sta ...
- OPTIONS 请求引发的分析
阅读提纲: 为什么会出现 OPTIONS 请求? 什么情况下会出现 OPTIONS 请求? OPTIONS 请求会发送什么内容? 跨域前端访问后端时,所有的 Ajax HTTP 请求都会先发送一个 O ...
- iSCSI 共享存储
iSCSI(Internet Small Computer System Interface,发音为/ˈаɪskʌzi/),Internet小型计算机系统接口,又称为IP-SAN,是一种基于 ...
- Windows Server 搭建企业无线认证(Radius认证方案)
认证协议介绍: 扩展认证协议EAP(Extensible Authentication Protocol) 是一个在无线网络或点对点连线中普遍使用的认证框架.它被定义在RFC 3748中,并且使RFC ...