《软件调试》学习笔记——004 (第一章 软件调试基础 part2)
2012-01-10 20:40
316 查看
《软件调试》学习笔记——004(第一章软件调试基础part2)
常用软件调试技术:
1)断点(Breakpoint)
断点和单步执行是最基本的调试手段。其基本思想是让被调试程序在执行到该处时,暂停被调试程序的执行;中断到调试器中,让调试人员进行分析。分析结束后,可以让被调试程序继续执行。
根据断点所处的空间,可以分为以下3种断点:
代码断点
设置在内存空间的代码段(即,断点地址为代码段的某个地址),当CPU执行该地址时,断点命中,中断到调试器。在源代码上(xx文件xx行)设定的断点都是代码断点。
数据断点
断点地址为数据段的某个地址,某个变量或数据的起始地址。当CPU访问该地址的数据时,断点命中,中断到调试器。
根据需要,可以定义触发断点的访问方式(读/写)、宽度(BYTE,WORD,DWORD)。
[EasyVCR@csdn]
怎样设置数据断点?
gdb:可以通过watchpoint来设置,当某个变量值改变(写)时中断到调试器;(gdb)helpwatch
WinDBG:???
I/O断点
断点地址为某一I/O地址。当CPU访问该I/O地址的端口时,断点命中,中断到调试器。
和数据断点类似,也可设置断点被触发的访问宽度(BYTE,WORD,DWORD)。
根据断点的设置方法可以,可以分为软件断点和硬件断点:
软件断点
软件断点通过向断点所在位置插入断点指令来实现。不同平台的断点指令可能不同。比如IA32架构CPU的断点指令为INT3(其对应的机器码为0xCC)。
断点指令只能设置上面提到的代码断点;而不能设置数据断点或者I/O断点。
[EasyVCR@csdn]
VC的Debug版程序,所有的局部变量都被初始化为0xCC;这样当程序"跑飞",将数据作为代码来执行时,就会解析成断点指令,如果是在调试器下被调试,就会中断下来;如果不是以被调试模式运行,操作系统也会给你一个选择加载调试器调试的机会。
而Release版的程序,局部变量被初始化为0x00;当程序"跑飞"时,操作系统也不会解析成断点指令。这也是Debug和Release版程序在运行时表现不一致的一个重要方面。
硬件断点
硬件断点通过CPU的调试寄存器设置。IA32架构CPU定义了8个调试寄存器(DR0~DR7)。对同一个调试会话,最多可同时设置4个硬件断点。
当中断到调试器时,被调试程序是处于【静止】状态。调试器会将被调试程序的状态保存到执行上下文(CONTEXT)中;当用户输入恢复执行的调试命令时,调试器再恢复被调试程序,使其继续运行。
[EasyVCR@csdn]
voidSuspendOrResumeProcess(DWORDdwPID,BOOLbSuspend)
{
HANDLEhSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,dwPID);
if(INVALID_HANDLE_VALUE!=hSnapshot)
{
THREADENTRY32te32={sizeof(THREADENTRY32)};
BOOLbFind=Thread32First(hSnapshot,&te32);
for(;bFind;bFind=Thread32Next(hSnapshot,&te32))
{
if(te32.th32OwnerProcessID==dwPID)
{
HANDLEhThread=OpenThread(THREAD_SUSPEND_RESUME,FALSE,te32.th32ThreadID);
if(NULL!=hThread)
{
bSuspend?SuspendThread(hThread):ResumeThread(hThread);
}
CloseHandle(hThread);
}
}
CloseHandle(hSnapshot);
}
}
ps,采用这种遍历线程的方式,对多线程程序,可能会导致各个线程中的执行情况与真实运行时有差异。
可能需要直接调用ntdll中的ZwSuspendProcess/ZwResumeProcess来挂起/恢复整个进程。
下图是Depends看到的ntdll的导出函数列表
typedefDWORD(WINAPI*PFSuspendProcess)(HANDLEhProcess);
typedefDWORD(WINAPI*PFResumeProcess)(HANDLEhProcess);
voidSuspendOrResumeProcess(DWORDdwPID,BOOLbSuspend)
{
HMODULEhNtDllLib=LoadLibrary(TEXT("ntdll.dll"));
PFSuspendProcessSuspendProcess=(PFSuspendProcess)GetProcAddress(hNtDllLib,"ZwSuspendProcess");
PFResumeProcessResumeProcess=(PFResumeProcess)GetProcAddress(hNtDllLib,"ZwResumeProcess");
if(SuspendProcess&&ResumeProcess)
{
HANDLEhProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwPID);
bSuspend?SuspendProcess(hProcess):ResumeProcess(hProcess);
CloseHandle(hProcess);
}
FreeLibrary(hNtDllLib);
}
追踪点与条件断点
追踪点(Tracepoint)
一种特殊的断点,当调试器中断到追踪点时,自动执行预先定义的追踪行为(通常为收集信息,比如打印某些变量的值),然后立即自动恢复被调试程序,使其继续运行。
[EasyVCR@csdn]
gdb:(gdb)helptracepoints
WinDBG:怎样设置Tracepoint?
条件断点(ConditionalBreakpoint)
一种特殊的断点,仅当定义的条件被满足时,调试器才中断被调试程序,让调试人员进行调试。
实际上,对调试器而言,每次执行到条件断点都会中断,只是中断后处理的行为不同:如果不满足条件断点定义的条件,则立即恢复被调试程序继续运行(调试人员感觉不到);如果满足,则中断被调试程序,让调试人员进行调试。
常用软件调试技术:
1)断点(Breakpoint)
断点和单步执行是最基本的调试手段。其基本思想是让被调试程序在执行到该处时,暂停被调试程序的执行;中断到调试器中,让调试人员进行分析。分析结束后,可以让被调试程序继续执行。
根据断点所处的空间,可以分为以下3种断点:
代码断点
设置在内存空间的代码段(即,断点地址为代码段的某个地址),当CPU执行该地址时,断点命中,中断到调试器。在源代码上(xx文件xx行)设定的断点都是代码断点。
数据断点
断点地址为数据段的某个地址,某个变量或数据的起始地址。当CPU访问该地址的数据时,断点命中,中断到调试器。
根据需要,可以定义触发断点的访问方式(读/写)、宽度(BYTE,WORD,DWORD)。
[EasyVCR@csdn]
怎样设置数据断点?
gdb:可以通过watchpoint来设置,当某个变量值改变(写)时中断到调试器;(gdb)helpwatch
WinDBG:???
I/O断点
断点地址为某一I/O地址。当CPU访问该I/O地址的端口时,断点命中,中断到调试器。
和数据断点类似,也可设置断点被触发的访问宽度(BYTE,WORD,DWORD)。
根据断点的设置方法可以,可以分为软件断点和硬件断点:
软件断点
软件断点通过向断点所在位置插入断点指令来实现。不同平台的断点指令可能不同。比如IA32架构CPU的断点指令为INT3(其对应的机器码为0xCC)。
断点指令只能设置上面提到的代码断点;而不能设置数据断点或者I/O断点。
[EasyVCR@csdn]
VC的Debug版程序,所有的局部变量都被初始化为0xCC;这样当程序"跑飞",将数据作为代码来执行时,就会解析成断点指令,如果是在调试器下被调试,就会中断下来;如果不是以被调试模式运行,操作系统也会给你一个选择加载调试器调试的机会。
而Release版的程序,局部变量被初始化为0x00;当程序"跑飞"时,操作系统也不会解析成断点指令。这也是Debug和Release版程序在运行时表现不一致的一个重要方面。
硬件断点
硬件断点通过CPU的调试寄存器设置。IA32架构CPU定义了8个调试寄存器(DR0~DR7)。对同一个调试会话,最多可同时设置4个硬件断点。
当中断到调试器时,被调试程序是处于【静止】状态。调试器会将被调试程序的状态保存到执行上下文(CONTEXT)中;当用户输入恢复执行的调试命令时,调试器再恢复被调试程序,使其继续运行。
[EasyVCR@csdn]
这个过程相当于自定义一个SuspendOrResumeProcess函数(遍历被调试进程中的所有线程,然后调用SuspendTread)
ps,采用这种遍历线程的方式,对多线程程序,可能会导致各个线程中的执行情况与真实运行时有差异。
可能需要直接调用ntdll中的ZwSuspendProcess/ZwResumeProcess来挂起/恢复整个进程。
下图是Depends看到的ntdll的导出函数列表
追踪点与条件断点
追踪点(Tracepoint)
一种特殊的断点,当调试器中断到追踪点时,自动执行预先定义的追踪行为(通常为收集信息,比如打印某些变量的值),然后立即自动恢复被调试程序,使其继续运行。
[EasyVCR@csdn]
gdb:(gdb)helptracepoints
WinDBG:怎样设置Tracepoint?
条件断点(ConditionalBreakpoint)
一种特殊的断点,仅当定义的条件被满足时,调试器才中断被调试程序,让调试人员进行调试。
实际上,对调试器而言,每次执行到条件断点都会中断,只是中断后处理的行为不同:如果不满足条件断点定义的条件,则立即恢复被调试程序继续运行(调试人员感觉不到);如果满足,则中断被调试程序,让调试人员进行调试。
相关文章推荐
- 《软件调试》学习笔记——003 (第一章 软件调试基础 part1)
- ASP.NET(VB.NET)学习笔记--第一章.语法基础
- 第一章 引言--《设计模式-可复用面向对象软件的基础》Erich Gamma
- 第一章 引言--《设计模式-可复用面向对象软件的基础》Erich Gamma
- Windows程序员进阶系列:《软件调试》之一:调试基础
- 6 软件调试基础知识
- 单片机成长之路(51基础篇) - 004 STC89C52MCU 软件实现系统复位
- 《汇编语言》学习笔记 第一章 基础知识
- 软件调试_阅读总结_2_CPU基础
- Windows程序员进阶系列:《软件调试》之一:调试基础
- 第一章、基础知识(Part2)--字符串
- <<WinDbg 调试实践基础>> 第一章:内存,寄存器和简单的运算 (1)
- 学习笔记_VC++深入详解(第一章)(part2)
- 软件调试基础--05Windbg调试器基础
- 软件调试笔记3 - CPU基础
- 软件调试笔记1 - 软件调试基础: 分类,调试技术概览
- 《Python基础教程第二版》学习笔记(一)第一章 基础知识
- 2008秋季-计算机软件基础-PPT课件-第一章 软件工程
- 软件测试基础(一) 概述
- 第一部分:基础知识(第一章)XAP 就是 ZIP