在lldb调试中调用c++函数 - 如何使用QuartzCore里面的日志消息

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

QuartzCore`x_logv:
    0x107d10e54 <+0>:   pushq  %rbp
    0x107d10e55 <+1>:   movq   %rsp, %rbp
    0x107d10e58 <+4>:   pushq  %r15
    0x107d10e5a <+6>:   pushq  %r14
    0x107d10e5c <+8>:   pushq  %r13
    0x107d10e5e <+10>:  pushq  %r12
    0x107d10e60 <+12>:  pushq  %rbx
    0x107d10e61 <+13>:  subq   $0x1018, %rsp
    0x107d10e68 <+20>:  movq   %rdx, %r14
    0x107d10e6b <+23>:  movq   %rsi, %rbx
    0x107d10e6e <+26>:  movl   %edi, %r15d
    0x107d10e71 <+29>:  movq   0x36268(%rip), %r13       ; (void *)0x000000010bede070: __stack_chk_guard
    0x107d10e78 <+36>:  movq   (%r13), %r13
    0x107d10e7c <+40>:  movq   %r13, -0x30(%rbp)
    0x107d10e80 <+44>:  movq   $0x0, -0x1038(%rbp)
    0x107d10e8b <+55>:  cmpq   $-0x1, 0x35c4d(%rip)      ; x_log_stream_slot + 7
    0x107d10e93 <+63>:  jne    0x107d10ff1               ; <+413>
    0x107d10e99 <+69>:  leal   -0x1(%r15), %eax
    0x107d10e9d <+73>:  cmpl   $0x1, %eax
    0x107d10ea0 <+76>:  ja     0x107d10ee4               ; <+144>
    0x107d10ea2 <+78>:  movb   0x35c18(%rip), %al        ; x_log_html
    0x107d10ea8 <+84>:  testb  %al, %al
    0x107d10eaa <+86>:  je     0x107d10ee4               ; <+144>
    0x107d10eac <+88>:  cmpl   $0x2, %r15d
    0x107d10eb0 <+92>:  leaq   0x20cd8(%rip), %rax       ; "err"
    0x107d10eb7 <+99>:  leaq   0x20cd5(%rip), %rdx       ; "warn"
    0x107d10ebe <+106>: cmoveq %rax, %rdx
    0x107d10ec2 <+110>: leaq   0x20ccf(%rip), %rsi       ; "<span class="%s">%s</span>"
    0x107d10ec9 <+117>: leaq   -0x1038(%rbp), %rdi
    0x107d10ed0 <+124>: xorl   %eax, %eax
    0x107d10ed2 <+126>: movq   %rbx, %rcx
    0x107d10ed5 <+129>: callq  0x107d13bd8               ; symbol stub for: asprintf
    0x107d10eda <+134>: testl  %eax, %eax
    0x107d10edc <+136>: cmovnsq -0x1038(%rbp), %rbx
    0x107d10ee4 <+144>: movq   0x35bed(%rip), %rdi       ; x_log_stream_slot
    0x107d10eeb <+151>: testq  %rdi, %rdi
    0x107d10eee <+154>: je     0x107d10f2e               ; <+218>
    0x107d10ef0 <+156>: callq  0x107d13e96               ; symbol stub for: pthread_getspecific
    0x107d10ef5 <+161>: movq   %rax, %r12
    0x107d10ef8 <+164>: testq  %r12, %r12
    0x107d10efb <+167>: je     0x107d10f2e               ; <+218>
    0x107d10efd <+169>: leaq   -0x1030(%rbp), %r15
    0x107d10f04 <+176>: movl   $0x1000, %esi
    0x107d10f09 <+181>: xorl   %edx, %edx
    0x107d10f0b <+183>: movl   $0x1000, %ecx
    0x107d10f10 <+188>: movq   %r15, %rdi
    0x107d10f13 <+191>: movq   %rbx, %r8
    0x107d10f16 <+194>: movq   %r14, %r9
    0x107d10f19 <+197>: callq  0x107d13bae               ; symbol stub for: __vsnprintf_chk
    0x107d10f1e <+202>: cmpl   $0xfff, %eax
    0x107d10f23 <+207>: jg     0x107d10f64               ; <+272>
    0x107d10f25 <+209>: movq   %r15, -0x1040(%rbp)
    0x107d10f2c <+216>: jmp    0x107d10f76               ; <+290>
    0x107d10f2e <+218>: movq   0x35b83(%rip), %rax       ; x_log_function
    0x107d10f35 <+225>: testq  %rax, %rax
    0x107d10f38 <+228>: je     0x107d10f4b               ; <+247>
    0x107d10f3a <+230>: movq   0x35b87(%rip), %rdx       ; x_log_function_info
    0x107d10f41 <+237>: movq   %rbx, %rdi
    0x107d10f44 <+240>: movq   %r14, %rsi
    0x107d10f47 <+243>: callq  *%rax
    0x107d10f49 <+245>: jmp    0x107d10fc8               ; <+372>
    0x107d10f4b <+247>: movq   0x35b5e(%rip), %rdi       ; x_log_file_handle
    0x107d10f52 <+254>: testq  %rdi, %rdi
    0x107d10f55 <+257>: je     0x107d10fa0               ; <+332>
    0x107d10f57 <+259>: movq   %rbx, %rsi
    0x107d10f5a <+262>: movq   %r14, %rdx
    0x107d10f5d <+265>: callq  0x107d13f98               ; symbol stub for: vfprintf
    0x107d10f62 <+270>: jmp    0x107d10fc8               ; <+372>
    0x107d10f64 <+272>: leaq   -0x1040(%rbp), %rdi
    0x107d10f6b <+279>: movq   %rbx, %rsi
    0x107d10f6e <+282>: movq   %r14, %rdx
    0x107d10f71 <+285>: callq  0x107d13f92               ; symbol stub for: vasprintf
    0x107d10f76 <+290>: testl  %eax, %eax
    0x107d10f78 <+292>: jle    0x107d10f8d               ; <+313>
    0x107d10f7a <+294>: movq   (%r12), %rdi
    0x107d10f7e <+298>: movslq %eax, %rdx
    0x107d10f81 <+301>: leaq   -0x1030(%rbp), %rsi
    0x107d10f88 <+308>: callq  0x107d12f64               ; x_stream_write
    0x107d10f8d <+313>: movq   -0x1040(%rbp), %rdi
    0x107d10f94 <+320>: cmpq   %r15, %rdi
    0x107d10f97 <+323>: je     0x107d10fc8               ; <+372>
    0x107d10f99 <+325>: callq  0x107d13d10               ; symbol stub for: free
    0x107d10f9e <+330>: jmp    0x107d10fc8               ; <+372>
    0x107d10fa0 <+332>: cmpl   $0x1, %r15d
    0x107d10fa4 <+336>: setne  %al
    0x107d10fa7 <+339>: movzbl %al, %eax
    0x107d10faa <+342>: orl    $0x4, %eax
    0x107d10fad <+345>: cmpl   $0x2, %r15d
    0x107d10fb1 <+349>: movl   $0x3, %edx
    0x107d10fb6 <+354>: cmovnel %eax, %edx
    0x107d10fb9 <+357>: xorl   %edi, %edi
    0x107d10fbb <+359>: xorl   %esi, %esi
    0x107d10fbd <+361>: movq   %rbx, %rcx
    0x107d10fc0 <+364>: movq   %r14, %r8
    0x107d10fc3 <+367>: callq  0x107d13bd2               ; symbol stub for: asl_vlog
    0x107d10fc8 <+372>: movq   -0x1038(%rbp), %rdi
    0x107d10fcf <+379>: testq  %rdi, %rdi
    0x107d10fd2 <+382>: je     0x107d10fd9               ; <+389>
    0x107d10fd4 <+384>: callq  0x107d13d10               ; symbol stub for: free
    0x107d10fd9 <+389>: cmpq   -0x30(%rbp), %r13
    0x107d10fdd <+393>: jne    0x107d1100b               ; <+439>
    0x107d10fdf <+395>: addq   $0x1018, %rsp
    0x107d10fe6 <+402>: popq   %rbx
    0x107d10fe7 <+403>: popq   %r12
    0x107d10fe9 <+405>: popq   %r13
    0x107d10feb <+407>: popq   %r14
    0x107d10fed <+409>: popq   %r15
    0x107d10fef <+411>: popq   %rbp
    0x107d10ff0 <+412>: retq
    0x107d10ff1 <+413>: leaq   0x35ae8(%rip), %rdi       ; x_log_once
    0x107d10ff8 <+420>: leaq   0x11(%rip), %rdx          ; x_log_init
    0x107d10fff <+427>: xorl   %esi, %esi
    0x107d11001 <+429>: callq  0x107d13c62               ; symbol stub for: dispatch_once_f
    0x107d11006 <+434>: jmp    0x107d10e99               ; <+69>
    0x107d1100b <+439>: callq  0x107d13b9c               ; symbol stub for: __stack_chk_fail

QuartzCore`x_logv:

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

// 257
    if (0 == x_log_file_handle) { // 254 (0 == rdi)
        // inline jmp 332
        // 367 call
        asl_vlog(0, 0, (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);
        // 270
        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方法。日志文件被写入了信息,这样我们就可以使用其自身的日志功能,查找收集一些内部的信息了。

时间: 2024-08-05 08:02:19

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

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

在lldb调试时,调用oc对象的方法不足为奇,因为msgSend是有原型导出的,oc对象的方法都运行期绑定的,绑定信息都在objc_class中.只要在调试中[receiver sel]之类,lldb就自动完成的整个由SEL通过msgSend路由到receiver的IMP方法并执行的整个过程.但是要调用c++函数则没有这么方便,虽然c++函数(包括成员函数和非成员函数)的链接符号有着函数原型的详细信息,但却不包括类的定义和名字空间的定义,即使lldb翻译出这样一个符号(symbol)Quartz

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

[VS开发]MFC中调用C函数模块的解决方案 标签(空格分隔): [VS开发] 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:最近调试基于MFC的程序,当通过外部C文件引入某个function的时候,又一次忘记了C文件与C++文件的区别,直接按照一般的方式,将函数声明放入头文件,将函数定义放入C文件,然后再MFC中通过包含头文件来引用对应的function,然而爆出了链接时无法定位的错误,本文就来梳理一下C++中调用C中功能函数的方法. 首先在C

Effective C++ Item 09-绝不在构造函数和析构函数中调用virtual函数

Item 09-绝不在构造函数和析构函数中调用virtual函数(Never call virtual functions during construction or destruction) Why? 由于base class构造函数的执行更早于derived class构造函数,当base class构造函数执行derived class的成员变量尚未初始化.如果期间调用的virtual函数下降至derived class阶层,要知道derived class的函数几乎必然取用local成

在printf语句中调用day_name函数并把i值传送给形参n

本例中定义了一个指针型函数day_name,它的返回值指向一个字符串.该函数中定义了一个静态指针数组name.name数组初始化赋值为八个字符串,分别表示各个星期名及出错提示.形参n表示与星期名所对应的整数.在主函数中,把输入的整数i作为实参,在printf语句中调用day_name函数并把i值传送给形参n.day_name函数中的return语句包含一个条件表达式,n值若大于7或小于1则把name[0]指针返回主函数输出出错提示字符串"Illegal day".否则返回主函数输出对应

C中调用Lua函数

我们先来看一个简单的例子: lua_State* L = NULL; // 内部调用lua函数 double f(double x, double y) { double z; lua_getglobal(L, "f"); // 获取lua函数f lua_pushnumber(L, x); // 压入参数x和y lua_pushnumber(L, y); if(lua_pcall(L, 2, 1, 0) != 0) error(L, "error running functi

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

在Apple官方的<Using Swift with Cocoa and Objectgive-C>一书中详细地介绍了如何在Objective-C中使用Swift的类以及如何在Swift中使用Objective-C中的类.在后半部分也介绍了如何在Swift中使用C函数,不过对于如何在C语言中使用Swift函数却只字未提.这里我就为大家分享一下如何在C语言中调用Swift函数. 我们首先要知道的是,所有Swift函数都属于闭包.其次,Swift函数的调用约定与Apple为Clang编译器贡献的B

Lua中调用C函数

Lua利用一个虚拟的堆栈来给C传递值或从C获取值.每当Lua调用C函数,都会获得一个新的堆栈,该堆栈初始包含所有的调用C函数所需要的参数值(Lua传给C函数的调用实参),并且C函数执行完毕后,会把返回值压入这个栈(Lua从中拿到C函数调用结果). 于此相关的C API有几个比较重要的定义如下: (1)typedef struct lua_State lua_State; lua虚拟机(或叫解释器),可以理解为一个thread,和一个完整的Lua虚拟环境的执行状态. (2)typedef int

Lua中调用C函数(lua-5.2.3)

Lua可以调用C函数的能力将极大的提高Lua的可扩展性和可用性. 对于有些和操作系统相关的功能,或者是对效率要求较高的模块,我们完全可以通过C函数来实现,之后再通过Lua调用指定的C函数. 对于那些可被Lua调用的C函数而言,其接口必须遵循Lua要求的形式,即typedef int (*lua_CFunction)(lua_State* L). 简单说明一下,该函数类型仅仅包含一个表示Lua环境的指针作为其唯一的参数,实现者可以通过该指针进一步获取Lua代码中实际传入的参数.返回值是整型,表示该

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

9.不在构造.析构函数中调用虚函数 1.在构造函数和析构函数中调用虚函数会产生什么结果呢? #include <iostream> using namespace std; class cls1{ public: cls1(){ newMake(); }; ~cls1(){ deleteIt(); }; virtual void newMake(){ cout<<"cls1 make"<<endl; } virtual void deleteIt()