데이터 베이스 MySQL 튜토리얼 读《软件调试》第九章

读《软件调试》第九章

Jun 07, 2016 pm 03:56 PM
cpu 오늘 선생님

今日读了张银奎老师的《软件调试》,前面的CPU和硬件相关的部分离得比较远,所以从第九章操作系统读起,今天的读书笔记: 9.2采集调试消息 调试事件分为8种 typedef enum _DBGKM_APINUMBER { DbgkmExceptionApi = 0, // 异常 DbgkmCreateThreadApi = 1, //

今日读了张银奎老师的《软件调试》,前面的CPU和硬件相关的部分离得比较远,所以从第九章操作系统读起,今天的读书笔记:

9.2采集调试消息
调试事件分为8种
typedef enum _DBGKM_APINUMBER
{
DbgkmExceptionApi = 0, // 异常
DbgkmCreateThreadApi = 1, // 创建线程
DbgkmCreateProcessApi = 2, // 创建进程
DbgkmExitThreadApi = 3, // 退出线程
DbgkmExitProcessApi = 4, // 进程退出
DbgkmLoadDllApi = 5, // 映射DLL
DbgkmUnloadDllApi = 6, // 反映射DLL
DbgkmErrorReportApi = 7, // 内部错误
DbgkmMaxApiNumber = 8, // 这组常量的最大值
} DBGKM_APINUMBER;


9.2.2 进程和线程创建消息
操作系统就支持向调试系统发送消息,这个我是没有想到的,具体过程如下:
创建用户态windows线程时,首先为线程建立必要的内核对象和数据结构,并分配栈(stack)空间,这些工作完成后,
该线程处于挂起状态(CREATE_SUSPEND), 而后进程管理器会通知环境子系统,环境子系统会作必要的设置和登记,最后
进程管理器会调用PspUserThreadStartup例程,准备启动该线程。
为了支持调试,PspUserThreadStartup总是会调用调试子系统的内核函数DbgkCreateThread,以便让调试子系统得到处理机会。


DbgkCreateThread会检查新创建线程所在的进程是否正在被调试(根据DebugPort是否为空),如果不是,便立即返回,
如果是,则会继续检查该进程的用户态运行时间(UserTime)是否为0,目的是判断该线程是否是进程中的第一个线程,如果是,
则通过DbgkSendApiMessage()函数向DebugPort发送DbgkmCreateProcessApi消息,如果不是,
则发送DbgkmCreateThreadApi消息。
调试器收到的进程创建(CREATE_PROCESS_DEBUG_EVENT,值为3)和线程创建(CREATE_THREAD_DEBUG_EVENT,值为2)事件就是源于这两个消息。


9.2.3 进程和线程退出消息 --- 与上面类似


9.2.4 模块映射和反映射消息
DLL(Dynamic-link Library)是Windows中使用最多的技术之一。如:
Windows内核文件NTOSKRNL.EXE虽然是EXE后缀,其实质是一个DLL;
NTDLL.DLL是连接用户态和操作系统内核的桥梁,用户态代码通过它访问内核服务;
Windows子系统DLL(KERNEL32.DLL,ADVAPI32.DLL,USER32.DLL,GDI32.DLL)是Windows API的载体;


观察进程中的DLL:
1.运行notepad.exe
2.启动VC6,通过Build>Start Debug>Attatch to Process...菜单弹出Attach Process对话框,然后选择notepad.
3. 通过Debug>Modules...菜单弹出模块列表,便可以看到notepad进程中的DLL了。
第二列是该模块在进程空间中的地址(虚拟地址,均小于0x80000000),可见这些模块都是位于用户空间中的。


存在于多个进程空间中的DLL,是否会重复占用内存?
否!当LoadLibrary()和LoadLibraryEx() API加载一个DLL时,会首先判断该DLL是否已经加载过,如果是,则不会重复加载,
只是将该DLL对应的内存页面映射(map)到目标进程的内存空间,并把该DLL的引用次数加1.
当进程退出或调用FreeLibrary() API要卸载一个DLL时,Windows会从进程的虚拟内存空间中把该DLL的映射删除(unmap),
并递减该DLL的引用次数,如果引用次数变为0,那么该DLL会被彻底移出内存。


9.2.5 异常消息
为了支持调试,系统会把被调试程序中发生的所有异常发送给调试器。
内核中KiDispatchException函数是分发异常的枢纽,它会给每个异常安排最多两轮被处理的机会,
对于每一轮处理机会,它都会调用调试子系统的DbgkForwardException函数来通知调试子系统。


总结:
系统的进程管理器、内存管理器和异常分发函数会调用调试子系统的Dbgk采集例程,来向调试子系统通报调试消息,
这些例程被调用后会根据当前进程的DebugPort字段来判断当前进程是否处于被调试状态。
如果不是,便忽略这次调用,直接返回;
如果是,便产生一个DBGKM_APIMSG结构,然后调用下一节将介绍的DbgkSendApiMessage函数来发送调试消息。

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

뜨거운 기사 태그

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

게임할 때 CPU 사용률은 얼마나 되어야 합니까? 게임할 때 CPU 사용률은 얼마나 되어야 합니까? Feb 19, 2024 am 11:21 AM

게임할 때 CPU 사용률은 얼마나 되어야 합니까?

Intel XTU를 사용하여 CPU를 언더볼팅하고 오버클럭하는 방법 Intel XTU를 사용하여 CPU를 언더볼팅하고 오버클럭하는 방법 Feb 19, 2024 am 11:06 AM

Intel XTU를 사용하여 CPU를 언더볼팅하고 오버클럭하는 방법

Win11에서 CPU 성능을 최대로 설정하는 방법 Win11에서 CPU 성능을 최대로 설정하는 방법 Feb 19, 2024 pm 07:42 PM

Win11에서 CPU 성능을 최대로 설정하는 방법

박스형 CPU와 대용량 CPU의 차이점 박스형 CPU와 대용량 CPU의 차이점 Jan 23, 2024 am 09:46 AM

박스형 CPU와 대용량 CPU의 차이점

CPU를 너무 많이 점유하는 WIN10 서비스 호스트의 동작 과정 CPU를 너무 많이 점유하는 WIN10 서비스 호스트의 동작 과정 Mar 27, 2024 pm 02:41 PM

CPU를 너무 많이 점유하는 WIN10 서비스 호스트의 동작 과정

144코어, 3D 스택 SRAM: Fujitsu, 차세대 데이터 센터 프로세서 MONAKA 자세히 설명 144코어, 3D 스택 SRAM: Fujitsu, 차세대 데이터 센터 프로세서 MONAKA 자세히 설명 Jul 29, 2024 am 11:40 AM

144코어, 3D 스택 SRAM: Fujitsu, 차세대 데이터 센터 프로세서 MONAKA 자세히 설명

컴퓨터 CPU의 클럭 주파수를 높이는 방법 컴퓨터 CPU의 클럭 주파수를 높이는 방법 Feb 20, 2024 am 09:54 AM

컴퓨터 CPU의 클럭 주파수를 높이는 방법

누출로 Intel Arrow Lake-U, -H, -HX 및 -S의 주요 사양 공개 누출로 Intel Arrow Lake-U, -H, -HX 및 -S의 주요 사양 공개 Jun 15, 2024 pm 09:49 PM

누출로 Intel Arrow Lake-U, -H, -HX 및 -S의 주요 사양 공개

See all articles