文档章节

debugger

精通吹水
 精通吹水
发布于 2016/04/17 10:37
字数 1515
阅读 79
收藏 3

debugger

文本将介绍调试器如何实现断点,单步,即时执行函数的功能。

GDB

在Linux C编程中,一般都使用GDB来进行调试代码。通过GDB我们可以实现断点,单步,即时执行这些调试手段。

INT 3 和 断点

80x86 CPU调试的核心就是通过INT 3 (80x86 CPU)中断来实现。当执行INT 3 的时候,在Linux中会引发SIGTRAP信号。从而进一步的实现具体的功能:查看变量,即时执行...。

而断点的实现就是通过INT 3来实现,实现的流程如下:

  1. 寻找到代码中被下断点的内存位置
  2. 记录原先位置的指令
  3. 使用INT 3来替换该指令,如果长度不符合,则使用NOP来填充。

这么做是因为涉及到偏移量的问题,不能简单的插入INT 3指令,而是采用替换的方式。这样子,就完成了打断点的功能。而当代码执行到刚刚下断点(INT 3指令)的时候,会执行如下流程:

  1. INT 3指令引发中断门
  2. Linux内核切换当前任务(被调试程序)到阻塞状态
  3. Linux唤醒调试器(GDB)告知被调试程序现在处于中断状态

此时,我们就可以通过GDB来查看被调试程序的变量,堆栈等信息。

TSS

那么问题来了:刚刚被INT 3替换的指令,如何执行?因为被调试程序的用户态EIP已经指向了INT 3下一条指令了

首先我们需要了解一下Linux下TSS的概念:

任务状态段(Task State Segment)是保存一个任务重要信息的特殊段。 TSS在任务切换过程中起着重要作用,通过它实现任务的挂起和恢复。所谓任务切换是指,挂起当前正在执行的任务,恢复或启动另一任务的执行。在任务切换过程中,首先,处理器中各寄存器的当前值被自动保存到TR所指定的TSS中;然后,下一任务的TSS的选择子被装入TR;最后,从TR所指定的TSS中取出各寄存器的值送到处理器的各寄存器中。由此可见,通过在TSS中保存任务现场各寄存器状态的完整映象,实现任务的切换。

所以在Linux中,是通过TSS来描述一个程序运行的状态,并且进行多任务轮转的。TSS结构图:

TSS

还原被替换的指令,然后通过修改EIP寄存器,将它指向被替换指令地址,因此被调试的程序可以执行刚刚被替换的指令。

JMP/CALL

80x86 CPU的EIP寄存器不能直接修改,而是需要通过专门指令来修改EIP寄存器:

  1. JMP : 直接跳转到指定目标代码
  2. CALL: 进行调用制定代码目标函数

在多任务模式下,通过JMP/CALL + TSS 来完成任务的切换。如:

jmp 0x1000:0x10000000 #TSS地址

这样子,就实现了任务的切换。

即时运行

即时运行指的是使用** GDB CALL 命令**来完成运行函数的功能。

这个功能和下断点的原理基本一致,也是通过替换指令和插入INT 3来完成。完成运行后,再还原之前被替换的代码,并且修改TSS中的EIP寄存器数值。

所以,即时运行的调用栈就是使用原先的调用栈,而非新开一个THREAD来执行即时运行代码。

JVM

Java的调试技术是非常成熟的,我们可以通过各种方式来调试Java代码,这也是VM的强大之处。

即时运行

在调试的时候,我们想知道一段代码执行的结果是什么。比如说,System.out.println(var)。这时候就需要使用即时运行的功能。

而即时运行功能也和GDB实现类似,调用栈也是使用原先的调用栈,而非新开THREAD运行及时代码:

public class Main {
	static public void main(String args[]) {
		Main main = new Main();
		main.a();
	}

	public void a() {
		System.out.println("A");
	}

	public void stack() {
		try {
			throw new RuntimeException("A");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

断点处运行:

Call Stack

执行结果为:

java.lang.RuntimeException: A
	at Main.stack(Main.java:18)
	at Main.a(Main.java:13)
	at Main.main(Main.java:9)

所以,及时运行的调用栈环境就是断点位置的环境。

远程调试

JVM也支持远程调试,这个功能对排查线上BUG是非常方便的,而这个功能是通过SOCKET来完成。

JVM调试参数:

-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,address=3999,suspend=n

说明:

参数含义
-XDebug启用调试。
-Xnoagent禁用默认sun.tools.debug调试器。
-Djava.compiler=NONE禁止 JIT 编译器的加载。
-Xrunjdwp加载JDWP的JPDA参考执行实例。
transport用于在调试程序和 VM 使用的进程之间通讯。
dt_socket套接字传输。
dt_shmem共享内存传输,仅限于 Windows。
server=y/nVM 是否需要作为调试服务器执行。
address=3999调试服务器的端口号,客户端用来连接服务器的端口号。
suspend=y/n是否在调试客户端建立连接之后启动 VM 。

这样子,就开启了JVM的调试功能,然后通过远程调试器连接上,既可以进行调试了。

因为通过Socket调试非常的方便,所以现在流行的语言基本上都支持远程调试的功能。

日志

在某些时候(生产环境),我们不能通过调试器来完成调试的功能,此时我们需要借助最原始的方式:日志

总结

一个好用的DEBUGGER能极大的增加软件开发效率。

参考

© 著作权归作者所有

共有 人打赏支持
下一篇: lock和wait+signal
精通吹水
粉丝 18
博文 56
码字总数 55035
作品 0
人事招聘
私信 提问
配置zend debugger

安装zend debugger 环境: xmapp mac 下周zend studio http://www.xue51.com/mac/1623.html 下周zend debugger http://www.zend.com/en/products/studio/downloads#Mac%20OS 下载后解压,把Zen......

晴天5539
06/05
0
0
一站式页面调试工具--Spy-Debugger

关于spy-debugger 1、一站式页面调试工具,远程调试任何手机浏览器页面,任何手机移动端webview(如:微信,HybirdApp等)HTTP/HTTPS。 2、spy-debugger内部集成了weinre。 3、支持HTTPS页面...

wuchangming
2016/04/26
2K
1
Java 远程调试

写服务端程序,在开发环境下打开远程调试还是非常有用的,还原现场非常容易,让请求方再发个请求即可。如果下来本地调试的话很多环境与管理服务的地址配置什么的都可能不一样,增加了可变因素...

mrliuze
2016/07/28
6
0
安装EPP的调试Zend Debugger

最近在工作中遇到的一个问题就是PHP程序的调试,PHP的程序可以直接在页面中显示出错误信息,但是如果是较大较复杂的程序,这种方式的开发效率就极其低下了,那么如何在IDE中可以对程序进行单...

王二狗子11
01/08
0
0
RN调试利器——React Native Debugger

余玮杰,2018年3月加入去哪儿网技术团队。目前在大住宿事业部/大前端/RN,参与开发大住宿RN和callcenter等相关业务。本人对前端相关领域的知识充满了兴趣,并且不断学习中。 前言 如何有效的...

Qunar技术沙龙
12/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

pyhanlp用户自定义词典添加实例说明

pyhanlp用户自定义词典添加实例说明 pyhanlp是python版封装的的HanLP,项目地址:https://github.com/hankcs/pyhanlp 经过测试,HanLP比nltk在中文分词和实体识别方面都更好用. 如何向pyhan...

左手的倒影
11分钟前
1
0
TypeError: 'dict_keys' object does not support indexing

在python2.x中,dict.keys()返回一个列表,在python3.x中,dict.keys()返回一个dict_keys对象,比起列表,这个对象的行为更像是set,所以不支持索引的。 解决方案:list(dict.keys())[index...

张欢19933
17分钟前
2
0
【HAVENT原创】单页面站点在 Nginx 下刷新报404 的问题

AngularJS / Vue / React 前端站点如果使用了单页面模式,在开发模式下直接使用 url 路由访问是正常的,但是在 nginx 下面会直接报 404 错误。 解决方式是加入 try_files $uri $uri/ /index....

HAVENT
22分钟前
1
0
聊聊flink的FsCheckpointStreamFactory

序 本文主要研究一下flink的FsCheckpointStreamFactory CheckpointStreamFactory flink-runtime_2.11-1.7.0-sources.jar!/org/apache/flink/runtime/state/CheckpointStreamFactory.java /**......

go4it
23分钟前
1
0
react-native-storage(数据存储)文档介绍

中文doc:仅供参考 import Storage from 'react-native-storage'; import {AsyncStorage} from 'react-native'; var storage = new Storage({ // 最大容量,默认值1000条数据循环存储 ......

凌宇之蓝
27分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部