JNI编程怎么跟踪调试dll?

简介: 本文主要讲解一下在jni开发中,如何调试C/C++编写的DLL模块。

原理


image.png

基于Windows操作系统的PE文件,理论是都是可以调试的,基于是否有源码,调试可以分为源码调试和二进制调试。在开发中,基本上都是使用源码进行调试,但是在一些逆向工程,或者没有源码的环境下则需要二进制调试,如使用Windbg、ollydbg等一些支持反汇编调试的调试工具,调试的原理就是调试器会在用户下断点对应的位置插入了Int3汇编指令,进行中断,有关调试的原理这里就不详阐述了。


调试过程


JNI调试其实就是源码调试技术,但是由于调用者是java程序,在Idea下貌似没有办法直接从Java的JNI接口进入C++实现函数进行调试,那么真的就无法调试了吗?当然不是,其实我们在使用VS编译生成二进制文件时,编译器会产生一个符号文件(*.pdb文件),只要调试器在调试该PE程序时,同时加载了这个pdb文件,那么调试器就会根据符号文件与源码进行匹配,从而实现源码调试。

1. 确保C++项目的编译选项中生成了pdb文件

image.png

2. 关闭编译优化

image.png

3. 查找java进程

编译完成后将生成的xxx.dll文件文件放入jni加载路径,运行java调用程序(最好先在java调用程序中下一个断点)。这时候,我们需要查找刚刚运行的进程?

这里我们可以利用两种方式查找运行进程:

  1. ProcessHacker找到该java进程的PID。
  2. 利用jps命令查找。

4. Attach Process

打开visual studio,并且打开DLL项目,使用Debug -> Attach Process的方式进行调试。

在进程列表中找到PID与java调用进程PID相同的java进程,点击Attache。

image.png


5. 调试

在代码中F9下断点,此时便可以放开IDEA中的断点,java进程在加载了DLL后,在运行至VS调试器设置的断点位置后,便会被断下,便可以开始调试。


image.png


注意


如果在java进程加载DLL后,断点无效,可以从两个方面排查:

  1. 调试的java进程不是调用者进程。
  2. java进程加载的DLL与该项目的pdb文件信息不匹配。
相关文章
|
5月前
|
数据采集 安全 测试技术
LabVIEW调用DLL时需注意的问题
LabVIEW调用DLL时需注意的问题
141 0
|
5月前
|
安全 数据处理 C++
LabVIEW调用外部DLL(动态链接库)
LabVIEW调用外部DLL(动态链接库)
33 0
|
7月前
|
开发框架 .NET
LabVIEW调用动态链接库DLL
LabVIEW调用动态链接库DLL
68 0
|
编译器 C语言
C程序调试过程常见的错误
在C语言编程,一般需要借助C相关的编译软件,例如,在Keil uVision5编程环境下,如果提示工具连接错误,则表示MDK安装程序有问题,重新卸载,并全部删除后重新再进行安装后即可。
C++ 编写DLL文件给易语言调用
  摸索了两天了,终于解决了所有问题,在此跟大家分享。   需要三个文件,dll_demo.h、dll_demo.cpp、dll_dome.def   直接上代码:   头文件如下: 1 #ifndef _DLL_DEMO_H_ 2 #define _DLL_DEMO_H_ 3 #ifdef DL...
2181 0
|
NoSQL Java Linux
JNI 调试技术
如果你像我一样是一个 Java 程序员,并且经常进行 JNI 代码的开发,那么你一定也体会到了调试 JNI 代码的困难,比如有一天突然程序意外崩溃了,我们很难搞清楚它到底是因为什么崩溃的。接下来我要介绍的这几个技术,可以帮助我们快速的解决上述问题。