开源项目asmjit——调用自定义方法demo以及windbg调试 asmjit调用自定义方法的demo VS调试 windbg调试asmjit生成的方法 调试过程中使用到的windbg命令介绍

asmjit是一个开源项目,使用它可以将代码即时的编译成机器码,也就是所谓的jit技术。

初次接触这个项目,编写了一个demo,学习它的使用方法。

现将编写的demo以及调试jit生成的机器码的过程总结出来,分享给大家

代码如下

#include "asmjit.h"

// [Dependencies - C]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace AsmJit;
#include <string>
#include <iostream>
using namespace std;


int add(int value1, int value2)
{
    cout << "arg1: " << value1 << "  arg2: " << value2 << endl;
    return value1 + value2;
}

int main(int argc, char* argv[])
{
    X86Compiler c;
    //记录日志,将编译细节输出到控制台
    FileLogger Logger(stdout);
    c.setLogger(&Logger);

    //新建一个无参数、无返回值的方法
    c.newFunc(kX86FuncConvDefault, FuncBuilder0<void>());
    //定义一个临时变量
    GpVar result(c.newGpVar());
    //给add方法传入参数
    c.push(Imm(9));
    c.push(Imm(10));
    //调用自定义的add方法
    c.call((void*)add);
    //方法结束
    c.endFunc();
    typedef void (*myfun)(void);
    //生成方法的机器码--真正的机器码
    myfun fun = asmjit_cast<myfun>(c.make());
    //调用刚刚生成的方法
    fun();

    //获取add方法的返回值
    __asm{

        mov value3, eax
    }

    cout << value3 << endl;
    //程序结束释放生成的方法占用的内存
    MemoryManager::getGlobal()->free(fun);

    return 0;
}

VS调试

用VS调试生成的fun方法,首先通过调试菜单,打开反汇编窗口,如下图

开源项目asmjit——调用自定义方法demo以及windbg调试
asmjit调用自定义方法的demo
VS调试
windbg调试asmjit生成的方法
调试过程中使用到的windbg命令介绍

通过F11单步调试进生成的fun方法,看到如下的反汇编代码

开源项目asmjit——调用自定义方法demo以及windbg调试
asmjit调用自定义方法的demo
VS调试
windbg调试asmjit生成的方法
调试过程中使用到的windbg命令介绍

由于显示一堆的??,无法知道生成的是什么指令,所以无法调试。

针对此问题在asmjit的google groups进行了提问

开源项目asmjit——调用自定义方法demo以及windbg调试
asmjit调用自定义方法的demo
VS调试
windbg调试asmjit生成的方法
调试过程中使用到的windbg命令介绍

下面是比较有用的回答

开源项目asmjit——调用自定义方法demo以及windbg调试
asmjit调用自定义方法的demo
VS调试
windbg调试asmjit生成的方法
调试过程中使用到的windbg命令介绍

根据Palo Marton的回答,这应该是VS的BUG。

windbg调试asmjit生成的方法

既然VS2012有BUG,那么就用windbg来调试吧

开源项目asmjit——调用自定义方法demo以及windbg调试
asmjit调用自定义方法的demo
VS调试
windbg调试asmjit生成的方法
调试过程中使用到的windbg命令介绍

启动后通过 lm 指令查看当前加载的模块

开源项目asmjit——调用自定义方法demo以及windbg调试
asmjit调用自定义方法的demo
VS调试
windbg调试asmjit生成的方法
调试过程中使用到的windbg命令介绍

上图看到,asmjit的符号文件还未加载。

对main方法设置断点 bp asmjit!main + 10,然后通过bl查看当前断点

开源项目asmjit——调用自定义方法demo以及windbg调试
asmjit调用自定义方法的demo
VS调试
windbg调试asmjit生成的方法
调试过程中使用到的windbg命令介绍

查看当前模块及其符号文件

开源项目asmjit——调用自定义方法demo以及windbg调试
asmjit调用自定义方法的demo
VS调试
windbg调试asmjit生成的方法
调试过程中使用到的windbg命令介绍

可以看到,这时asmjit的符号文件已经加载了。

通过g命令直接运行。

此时由于符号文件已经加载,windbg会根据符号文件加载对应的源文件

开源项目asmjit——调用自定义方法demo以及windbg调试
asmjit调用自定义方法的demo
VS调试
windbg调试asmjit生成的方法
调试过程中使用到的windbg命令介绍

这时断在了刚才下的断点处,Alt+7打开反汇编窗口

开源项目asmjit——调用自定义方法demo以及windbg调试
asmjit调用自定义方法的demo
VS调试
windbg调试asmjit生成的方法
调试过程中使用到的windbg命令介绍

通过p命令进行单步调试(相当于VS中的F10),t命令进行步入调试(相当于VS中的F11)。

执行到fun方法时,通过t命令进入方法内就可以看到生成的fun方法的反汇编代码了

开源项目asmjit——调用自定义方法demo以及windbg调试
asmjit调用自定义方法的demo
VS调试
windbg调试asmjit生成的方法
调试过程中使用到的windbg命令介绍

调试过程中使用到的windbg命令介绍

lm:List Loaded Modules,lm 命令显示已经加载的模块,输出信息包括模块的状态和路径。

bp:bp命令设置程序断点。

bl:BreakPoint List ,bl命令列出当前存在的断点信息列表。

p:Step,p命令执行一条指令或者一句源代码,然后展示所有寄存器的结果,相当于VS调试中的F10

g:Go,g命令开始执行当前进程或线程,相当于VS中的F5

t:Trace,t命令相当于VS中的F11

gu:Go Up,gu命令会使程序一直执行,知道当前的方法执行结束。相当于VS中的Shift+F11