一种实现用户态调试器调试单个函数的方法及系统技术方案

技术编号:2913501 阅读:216 留言:0更新日期:2012-04-11 18:40
本发明专利技术公开了一种实现用户态调试器调试单个函数的方法及系统,系统包括符号表操作模块、寄存器操作模块、内存操作模块、运行控制模块、运行环境构建模块;方法为:A.符号表操作模块分析当前的被调试程序及其动态库的符号信息,建立哈希表;运行控制模块从被调试程序的任务中选择一个作为待处理任务;B.运行控制模块从哈希表查找线程创建库函数,找到后停止运行待处理任务;C.运行环境构建模块依据线程创建库函数及待调试函数,调用寄存器和内存操作模块来修改待处理任务的各寄存器和堆栈中的值,以改变待处理任务的行为,使其在之后运行时创建线程来执行待调试函数,之后运行待处理任务。采用本发明专利技术,实现了在各种CPU上通过创建线程来运行单个函数的功能。

【技术实现步骤摘要】

本专利技术涉及调试器的实现技术,尤其涉及一种实现用户态调试器调试单个函数的方法及系统
技术介绍
调试器是用来帮助开发人员定位程序故障的一种工具软件。目前的调试器总体分为两类:内核级调试器和用户态调试器。内核级调试器能够跟踪和调试运行在内核态的任务;用户态调试器只能对运行在用户态的任务进行调试。调试器提供了设置断点,查看变量、寄存器、显示堆栈和求表达式值等基本调试功能,以及控制程序运行的单步跳过,单步进入,继续运行等功能。这些功能对于程序员跟踪和发现故障起着重要作用。在程序设计语言中,函数作为逻辑上相对独立的代码片断,能够完成函数设计者所指定的功能。函数功能的正确性对程序整体行为的正确性起着决定作用,因此,如何针对单个函数进行调试并验证其正确性,成为调试的一种需要。以WindRiver公司的Vxworks(一种嵌入式实时操作系统)为例,它提供的shell调试器,就具备调试单个函数的功能。通过在shell中执行命令,创建新的任务,该任务执行命令指定的函数,并能够对其进行调试。Vxworks的shell调试器属于内核级调试器,被运行起来的函数是在内核态运行的。其功能的实现依赖于内核提供的创建任务的接口函数,通过传入要运行的函数的地址以及函数参数来完成。由此可知,在内核态下,只需要调用内核任务创建函数,并传入要创建函数的入口地址,即可实现调试单个函数的功能。-->然而,对于用户态调试器,在用户态下没有一个统一的接口实现在其它进程中创建新线程。具体的说,用户态的程序通常被称为一个进程,一个进程可以拥有多个线程,线程之间共享同一个进程的资源;而进程之间的地址空间却是相互独立的,每个进程都有自己的虚拟地址空间,一个进程不能直接读写其它进程的虚拟地址空间的内容;同时,操作系统没有提供在其它进程中创建线程运行单个函数的接口。因此,用户态调试器作为用户态下运行的一个普通进程,要实现在被调试任务中创建线程运行单个函数,无法直接利用操作系统的接口完成。在目前的用户态调试器中还没有创建线程运行单个函数功能的实现。
技术实现思路
本专利技术所要解决的技术问题是提供一种实现用户态调试器调试单个函数的方法,以及实现该方法的系统。为解决上述技术问题,本专利技术是通过以下技术方案实现的:一种实现用户态调试器调试单个函数的方法,所述用户态调试器在收到调试所述单个函数的命令后,将该函数作为当前的待调试函数,并作以下处理:A、对当前的被调试程序以及被调试程序加载的动态库的符号信息进行分析,根据分析结果建立哈希表;同时,从所述被调试程序的任务中选择一个任务作为待处理任务;B、在所述哈希表中查找线程创建库函数的入口地址,当找到后,停止所述待处理任务的运行;C、以所述线程创建库函数及所述待调试函数为依据,修改所述待处理任务的各寄存器和堆栈中的值,以改变所述待处理任务的行为,使其在之后运行时创建线程来执行所述待调试函数,修改成功后运行所述待处理任务。其中,所述步骤B中,在停止所述待处理任务的运行之后,还包括:-->将当前所述待处理任务的全部寄存器和堆栈中的值进行保存;步骤C之后还包括:根据所述待处理任务返回的信号确认所述待调试函数的运行是否结束,若已结束,则将所述待处理任务的全部寄存器和堆栈中的值恢复为所述步骤B中在停止所述待处理任务的运行之后所保存的值。其中,所述步骤B中还包括:若在所述哈希表中未查找到线程创建库函数的入口地址,则将线程库加载到所述被调试程序中,加载成功后,将所述线程库的符号信息添加入所述哈希表中,再从该哈希表中查找出所述线程创建库函数的入口地址。其中,步骤B中,所述线程库加载到所述被调试程序中的方法为:①在标准C函数库中查找动态库加载函数的入口地址;②将所述待处理任务的程序计数器的值设置为动态库加载函数的入口地址;③从所述待处理任务的堆栈指针寄存器中读取当前栈顶的地址;以此地址为起始地址,在所述待处理任务的堆栈上构建所述动态库加载函数的调用栈帧,该调用栈帧中包括动态库路径、模式、动态库路径地址及返回地址参数;其中,所述动态库路径为线程库的路径,所述模式为所述线程库的加载模式,所述动态库路径地址为所述线程库的路径地址;④设置待处理任务的堆栈指针寄存器的值为新的栈顶地址。其中,所述步骤C中,所述待处理任务的各寄存器和堆栈中的值的修改方法为:e1、设置所述待处理任务的程序计数器的值为线程创建库函数的入口地址;e2、从所述待处理任务的堆栈指针寄存器中读取当前栈顶的地址;e3、以所述当前栈顶的地址为起始地址,在所述待处理任务的堆栈-->中,构建所述待调试函数的函数调用栈帧;e4、设置所述堆栈指针寄存器中的指针指向新的栈顶地址。其中,所述步骤e3中,所述待调试函数的函数调用栈帧的构建过程包括:m1、在所述堆栈上分配存放线程内部标识的局部变量的空间,写入所述线程内部标识的局部变量;m2、在堆栈上分配存放待调试函数的参数的空间,写入所述待调试函数的各项参数;m3、在所述堆栈上分配空间,依次写入待调试函数的入口地址、线程属性、线程内部标识局部变量的地址。一种实现用户态调试器调试单个函数的系统,包括符号表操作模块、寄存器操作模块、内存操作模块,还包括:运行控制模块、运行环境构建模块;所述符号表操作模块,用于对被调试程序以及被调试程序所加载的动态库的符号信息进行分析,根据分析结果建立哈希表;所述寄存器操作模块,用于对被调试程序的任务的各寄存器的值进行读写操作;所述内存操作模块,用于对被调试程序的任务的堆栈中的值进行读取和修改的操作;所述运行控制模块,用于接收调试单个函数的命令,将所述单个函数作为待调试函数,进行以下操作:从当前被调试程序的任务中选取一个任务作为待处理任务,调用符号表操作模块建立哈希表并从中查找线程创建库函数的入口地址,然后停止所述待处理任务的运行;控制运行环境构建模块以所述线程创建库函数及待调试函数为依据来改变所述待处理任务的行为,使该任务在之后运行时创建线程来执行所述待调试函数,并在修改完成之后启动所述待处理任务的运行;-->所述运行环境构建模块,用于以所述线程创建库函数及待调试函数为依据,通过调用寄存器操作模块和内存操作模块修改所述待处理任务的各寄存器和堆栈的值来改变所述待处理任务的行为,为所述待调试函数创建运行环境。上述系统中,还包括动态库加载模块,用于向被调试程序中加载指定的动态库;所述运行控制模块,还用于在从所述哈希表中未查找到线程创建库函数的入口地址时,通过调用动态库加载模块向所述被调试程序中加载线程库,并调用符号表操作模块将所述线程库的符号信息添加入所述哈希表中,然后从该哈希表中重新查找所述线程创建库函数。上述系统中,还包括信号处理模块和运行环境恢复模块;所述信号处理模块,用于等待接收所述待处理任务在运行过程中返回的信号,根据信号的类型判断所述待调试函数的运行是否结束,若已结束,则通知运行环境恢复模块;所述运行环境恢复模块,用于调用寄存器操作模块,保存所述待处理任务的各寄存器和堆栈在被所述运行环境构建模块修改之前的值,并在收到信号处理模块的通知后,将所述待处理任务的各寄存器和堆栈的值恢复为之前保存的值。本专利技术具有以下有益效果:采用本专利技术,能够在各种CPU上实现创建线程运行单个函数的功能,克服了目前的用户态调试器中缺少对运本文档来自技高网
...

【技术保护点】
一种实现用户态调试器调试单个函数的方法,其特征在于,所述用户态调试器在收到调试所述单个函数的命令后,将该函数作为当前的待调试函数,并作以下处理: A、对当前的被调试程序以及被调试程序加载的动态库的符号信息进行分析,根据分析结果建立哈希 表;同时,从所述被调试程序的任务中选择一个任务作为待处理任务; B、在所述哈希表中查找线程创建库函数的入口地址,当找到后,停止所述待处理任务的运行; C、以所述线程创建库函数及所述待调试函数为依据,修改所述待处理任务的各寄存器和 堆栈中的值,以改变所述待处理任务的行为,使其在之后运行时创建线程来执行所述待调试函数,修改成功后运行所述待处理任务。

【技术特征摘要】
1、一种实现用户态调试器调试单个函数的方法,其特征在于,所述用户态调试器在收到调试所述单个函数的命令后,将该函数作为当前的待调试函数,并作以下处理:A、对当前的被调试程序以及被调试程序加载的动态库的符号信息进行分析,根据分析结果建立哈希表;同时,从所述被调试程序的任务中选择一个任务作为待处理任务;B、在所述哈希表中查找线程创建库函数的入口地址,当找到后,停止所述待处理任务的运行;C、以所述线程创建库函数及所述待调试函数为依据,修改所述待处理任务的各寄存器和堆栈中的值,以改变所述待处理任务的行为,使其在之后运行时创建线程来执行所述待调试函数,修改成功后运行所述待处理任务。2、如权利要求1所述的实现用户态调试器调试单个函数的方法,其特征在于,所述步骤B中,在停止所述待处理任务的运行之后,还包括:将当前所述待处理任务的全部寄存器和堆栈中的值进行保存;步骤C之后还包括:根据所述待处理任务返回的信号确认所述待调试函数的运行是否结束,若已结束,则将所述待处理任务的全部寄存器和堆栈中的值恢复为所述步骤B中在停止所述待处理任务的运行之后所保存的值。3、如权利要求1或2所述的实现用户态调试器调试单个函数的方法,其特征在于,所述步骤B中还包括:若在所述哈希表中未查找到线程创建库函数的入口地址,则将线程库加载到所述被调试程序中,加载成功后,将所述线程库的符号信息添加入所述哈希表中,再从该哈希表中查找出所述线程创建库函数的入口地址。4、如权利要求3所述的实现用户态调试器调试单个函数的方法,其特征在于,步骤B中,所述线程库加载到所述被调试程序中的方法为:①在标准C函数库中查找动态库加载函数的入口地址;②将所述待处理任务的程序计数器的值设置为动态库加载函数的入口地址;③从所述待处理任务的堆栈指针寄存器中读取当前栈顶的地址;以此地址为起始地址,在所述待处理任务的堆栈上构建所述动态库加载函数的调用栈帧,该调用栈帧中包括动态库路径、模式、动态库路径地址及返回地址参数;其中,所述动态库路径为线程库的路径,所述模式为所述线程库的加载模式,所述动态库路径地址为所述线程库的路径地址;④设置待处理任务的堆栈指针寄存器的值为新的栈顶地址。5、如权利要求1或2所述的实现用户态调试器调试单个函数的方法,其特征在于,所述步骤C中,所述待处理任务的各寄存器和堆栈中的值的修改方法为:e1、设置所述待处理任务的程序计数器的值为线程创建库函数的入口地址;e2、从所述待处理任务的堆栈指针寄存器中读取当前栈顶的地址;e3、以所述当前栈顶的地址为起始地址,在所述待处理任务的堆栈中,构建所述待调试函数的函数调用栈帧;e4、设置所述堆栈指针寄存器中的指针指向新的栈...

【专利技术属性】
技术研发人员:向红
申请(专利权)人:中兴通讯股份有限公司
类型:发明
国别省市:94[中国|深圳]

网友询问留言 已有0条评论
  • 还没有人留言评论。发表了对其他浏览者有用的留言会获得科技券。

1