一种公共数据的多线程访问轨迹的分析方法与流程

文档序号:31718500发布日期:2022-10-04 22:37阅读:62来源:国知局
一种公共数据的多线程访问轨迹的分析方法与流程

1.本发明属于计算机技术领域,具体涉及一种公共数据的多线程访问轨迹的分析方法。


背景技术:

2.在多线程程序中,多个线程并发访问公共变量是一种常见现象。当多个线程对公共变量进行访问出现错误时,现有的增加断点、单步交互式等程序调试方式主要存在以下问题:一是错误复现困难,由于操作系统分配cpu给某个线程的时机和顺序具有不确定性,某个错误可能需要反复交互式调试才能再次出现,增加了调试分析的难度;二是错误定位费时,错误复现后在单步交互式调试模式下,需要程序员记忆错误时多个线程访问变量前后的历史场景,再分析每个线程的调用栈等情况,过程复杂费时;三是日志形式不直观,日志中记录了程序的执行过程,然而日志记录的内容十分有限,往往缺乏线程调用栈、相关变量等有用信息,此外,通过日志分析需要反复查看文本日志,这些都增加了程序调试分析的难度。


技术实现要素:

3.有鉴于此,本发明提供了一种公共数据的多线程访问轨迹的分析方法,实现了基于二进制代码调试过程中根据需要记录的代码执行相关信息完成对目标变量执行过程的精准跟踪与记录。
4.本发明提供的一种公共数据的多线程访问轨迹的分析方法,具体包括以下步骤:步骤1、确定源代码中与目标变量相关的所有变量为目标相关变量,在所有目标相关变量处增加语义标注;步骤2、在编译器编译所述源代码的过程中,根据语义标注识别目标相关变量后获取针对目标相关变量的所有写操作代码,在写操作代码的前后均增加自定义断点语句生成二进制代码;所述自定义断点语句包括特定opcode、变量id及源代码行号,特定opcode为设定的无效opcode;步骤3、使用调试器调试所述二进制代码,当调试器接收到invalidopcode异常消息后,设置处理器的异常处理标志为异常,若异常消息相关无效opcode为自定义断点语句中所的特定opcode,则执行步骤4;否则执行步骤5;当处理器抛出异常时,执行步骤6;步骤4、根据自定义断点语句记录信息实体的信息及信息实体间的对应关系形成断点历史数据,所述信息实体包括断点指令地址a、变量id、源代码行号、线程、栈顶函数及变量;步骤5、设置处理器的异常处理标志为继续执行,调试器计算断点指令地址a之后跳过自定义断点语句的长度的地址位置b,若地址位置b存在则将指令地址b作为当前指令地址执行步骤3;若指令地址b不存在或处理器抛出异常,则执行步骤6;步骤6、令迭代执行次数自加1,若迭代执行次数小于或等于阈值则执行步骤3,否
则结束调试执行步骤7;若处理器已抛出异常则结束调试执行步骤7;步骤7、根据断点历史数据完成对变量及线程的分析。
5.进一步地,所述步骤1中的所述目标变量采用源代码文件全路径、源代码行号及变量名描述。
6.进一步地,所述步骤1中确定源代码中与目标变量相关的所有变量为目标相关变量的方式为:采用污点分析方法确定与目标变量相关的目标相关变量。
7.进一步地,所述步骤1中确定源代码中与目标变量相关的所有变量为目标相关变量的方式为:采用符号执行方法确定与目标变量相关的目标相关变量。
8.进一步地,所述自定义断点语句还包括源代码文件信息,所述源代码文件信息为源代码文件的哈希值。
9.进一步地,所述步骤4中根据自定义断点语句记录信息实体的信息及信息实体间的对应关系形成断点历史数据的过程中,根据源代码文件信息获取二进制代码所对应的源代码文件。
10.进一步地,所述步骤4中根据自定义断点语句记录信息实体的信息及信息实体间的对应关系形成断点历史数据的过程包括以下步骤:步骤4.1、获取断点指令地址a所在线程的调用栈a,计算调用栈a的栈顶变量地址列表与目标相关变量的交集,记录交集中所有的变量及其当前值;步骤4.2、获取除断点指令地址a所在线程以外的其他线程的调用栈栈顶的变量地址列表与目标相关变量的交集,若交集不为空则记录该线程的调用栈,及交集中的变量及对应的当前值;若交集为空则不处理。
11.进一步地,所述步骤7中根据断点历史数据完成对变量及线程的分析的方式为:根据输入的条件查询其首次和末次出现的时间点,再以时间点为条件查询已存在的实体及其关系;当实体存在而关系数据不存在时,以包含该实体且与该时间点最接近的前一个断点时间点的关系数据作为查询结果。
12.进一步地,所述步骤6中所述结束调试之后将二进制代码中自定义断点语句中的特定opcode修改为nop指令。
13.进一步地,所述步骤6中所述结束调试之后删除源代码中的语义标注后重新编译生成二进制代码。
14.有益效果:1、本发明通过修改编译器使其在对源代码编译过程中能够根据语义标注信息增加断点,通过修改调试器使其在运行二进制代码的过程中能够根据需要记录断点处代码执行相关信息,由此能够实现对目标变量执行过程的精准跟踪与记录,基于记录的信息能够确定针对公共数据的多线程访问轨迹,从而有效降低了调试过程的难度,提高了调试的效率及精度。
15.2、本发明通过获取断点指令地址位置处处理器内的线程的调用栈,并从调用栈的栈顶变量地址列表中选择与目标相关变量相同的变量记录其变量取值,以有效减小记录的信息量优化记录信息,从而避免由记录所有线程的信息所导致的消耗过多资源的问题。
附图说明
16.图1为本发明提供的一种公共数据的多线程访问轨迹的分析方法的流程图。
具体实施方式
17.下面结合附图并举实施例,对本发明进行详细描述。
18.本发明提供了一种公共数据的多线程访问轨迹的分析方法,其核心思想是:根据设定的目标变量确定待分析源代码中的目标相关变量,并在源代码的目标相关变量处增加语义标注;在编译器编译上述源代码的过程中,在语义标注位置的前后均插入断点指令,断点指令设计为特定的无效opcode,该无效opcode会触发处理器产生类型为invalidopcode的异常,之后形成待分析的二进制代码;在调试器运行上述二进制代码的过程中,当遇到上述断点时记录代码运行相关信息,直到出现异常或达到设定的迭代次数为止;最后根据记录的代码运行相关信息完成对公共数据的多线程访问轨迹的分析。
19.本发明提供了一种公共数据的多线程访问轨迹的分析方法,流程如图1所示,包括以下步骤:步骤1、开发者确定其所关注的源代码中的目标变量,目标变量采用源代码文件全路径、源代码行号及变量名等信息描述;确定源代码中与目标变量相关的所有变量为目标相关变量,在源代码内所有目标相关变量处增加语义标注。
20.其中,在源代码内所有目标相关变量处所增加的语义标注可表示为“@breakpoint”等形式。
21.在漏洞分析中通常使用污点分析方法将所感兴趣的数据标记为污点数据,再通过跟踪与污点数据相关的信息的流向就能够确定污点数据是否会影响关键的程序操作,进而挖掘程序漏洞。本发明中,可采用污点分析方法确定源代码中与目标变量相关的所有变量为目标相关变量,即将目标变量标记为污点数据,采用污点分析方法即可获取与之相关的变量信息。除此之外,还可采用符号执行等方法获取与目标变量相关的所有变量。
22.步骤2、在编译器编译上述源代码的过程中,根据语义标注识别其中的目标相关变量,获取目标相关变量的地址,得到针对该地址的所有写操作代码,并在写操作代码的前后均增加自定义断点语句来新增断点,得到二进制代码。
23.其中,自定义断点语句包括特定opcode、变量id及源代码行号等,特定opcode是根据需要设定的无效opcode,也是具有唯一性的字节码,变量id为当前变量在目标相关变量中的唯一编号。无效opcode指的是处理器(cpu)无法识别的opcode,当处理器遇到该类opcode时会抛出invalidopcode异常,需要由调试器预先注册invalidopcode异常的处理接口进行处理。此外,为了提高获取源文件的效率,本发明在自定义断点语句中还可增加源代码文件信息,源代码文件信息为源代码文件的哈希值,调试代码通过哈希值与源代码文件全路径的对应关系即可迅速获取源代码文件。
24.步骤3、使用调试器加载被调试二进制代码。
25.步骤4、使用调试器启动调试被调试二进制代码,设置被调试二进制代码的第一行代码的指令地址为当前指令地址。
26.步骤5、处理器根据当前指令地址执行指令,当调试器接收到invalidopcode异常后,设置处理器的异常处理标志为异常,若当前无效opcode为自定义断点语句中包含的特
定opcode,则表明该断点为当前调试所设定的断点,执行步骤6;否则不处理当前异常并执行步骤7;当处理器抛出异常时,执行步骤8。
27.步骤6、根据自定义断点语句记录断点指令地址a、变量id、源代码行号、线程、栈顶函数、变量等信息实体,以及信息实体间的相互对应关系,形成断点历史数据。
28.若自定义断点语句中包含源代码文件信息,则根据源代码文件信息获取当前二进制代码所对应的源代码文件。
29.步骤7、将处理器的异常处理标志设置为继续执行,调试器解析被调试二进制代码的调试信息,计算断点指令地址a之后跳过自定义断点语句的长度的地址位置b,若地址位置b存在则将指令地址b作为当前指令地址执行步骤5;若指令地址b不存在或处理器抛出异常,则执行步骤8。
30.步骤8、令迭代执行次数自加1,若迭代执行次数小于或等于阈值则执行步骤4,否则结束对被调试二进制代码的调试执行步骤9;若处理器已抛出异常则结束对被调试二进制代码的调试执行步骤9。
31.步骤9、根据断点历史数据完成对变量及线程的分析。
32.其中,上述步骤6中记录信息实体的过程为:当接收到待记录的信息实体时,查询当前信息实体是否已被记录,若未被记录则加入信息实体列表中,同时记录加入断点的时间;若已记录则仅在信息实体属性发生变化时更新信息实体的相关属性。
33.上述信息实体间的相互关系,包括线程与栈顶函数的对应关系、栈顶函数与变量的对应关系、变量与变量之间的依赖关系三类关系,信息实体列表以断点时间作为唯一索引。进一步地,由于变量在使用期间名称不会变化,因此为减小存储空间,仅记录变量取值的变化。
34.此外,为避免由记录所有线程的信息所导致的消耗过多的资源,本发明在步骤6中还提供了减小记录的信息量优化记录信息的方式,具体包括以下步骤:步骤6.1、获取断点指令地址a所在线程的调用栈a,计算调用栈a的栈顶变量地址列表与目标相关变量的交集,记录交集中所有的变量及其当前值;步骤6.2、获取除断点指令地址a所在线程以外的其他线程的调用栈栈顶的变量地址列表与目标相关变量的交集,若交集不为空则记录该线程的调用栈,及交集中的变量及对应的当前值;若交集为空则不处理。
35.步骤6.3、将上述所有信息,以当前的变量id为索引,建立该变量id与上述信息的映射关系。
36.进一步地,本发明提供了步骤9中根据断点历史数据完成对变量及线程的分析的以下方式:按照时间点查询:以输入的时间点为条件查询数据,查询该时间点已存在的实体及其关系;当实体存在而该时间点的关系数据不存在时,查询包含该实体且与该时间点最接近的前一个断点时间点的关系数据;按照变量查询:查询到该变量的首次和末次出现的时间点,采用按照时间点查询的方式依次查询各个时间点的数据,分析变量变化的整个历史是否异常。
37.按照线程查询:查询到该线程的首次和末次出现的时间点,采用按照时间点查询的方式依次查询各个时间点的数据,分析线程访问变量的历史是否异常。
38.按照变量值变化历史查询:以步骤6.3中变量id为查询条件,查找特定变量的值每次被修改时的数据,分析修改变量值的线程是否异常,变量值改变前后的大小是否异常。
39.进一步地,在上述调试结束后,为了保证用户执行该二进制代码的正确性,本发明提供了以下三种方式关闭新增断点:第一种是将二进制代码中自定义断点语句中的特定opcode修改为nop指令;第二种是删除源代码中的语义标注后重新编译生成二进制代码;第三种是用户忽略包含特定opcode的自定义断点语句,即忽略断点。
40.实施例:本实施例为通过修改llvm编译器及lldb调试器,实现本发明提供的一种公共数据的多线程访问轨迹的分析方法,具体包括以下步骤:s1、开发者确定源代码文件中其所关心的目标变量,包括源代码文件全路径、源代码行号及变量名。
41.s2、通过污点分析,确定与目标变量相关的所有相关变量的列表variablelist,在源代码文件中的所有相关变量处增加语义标注(annotation),例如增加形如@breakpoint的语义标注。
42.s3、修改llvm编译器,使其对源代码文件中的每一个语义标注@breakpoint,执行以下操作:s3.1、预编译处理器识别语义标注@breakpoint及其变量,并依据变量的地址和针对该地址的写操作识别针对该变量的所有的写操作代码;s3.2、编译过程中在该变量的每个写操作代码的前后,都插入自定义断点语句。
43.s3.3、建立自定义断点链表breakpointlist [指令地址,文件名,行号]用于保存自定义断点语句相关信息,新增段section breakpoint保存链表breakpointlist,将新增段section breakpoint写入二进制代码的尾部。
[0044]
s4、修改调试器lldb,实现以下功能:s4.1、lldb在加载被调试程序时,识别新增段section breakpoint,并解析成自定义断点链表breakpointlist。
[0045]
s4.2、被调试程序运行到自定义断点语句时,lldb会接收到sigtrap信号及其指令地址,lldb依据指令地址到自定义断点链表中查询,若存在对应的记录,则可判定为命中自定义的断点。
[0046]
s4.3、命中断点后,设置处理器的异常处理标志为异常,记录当前断点指令地址,同时为避免记录所有线程的信息,减小记录的信息量,仅记录以下三类信息:一是记录当前线程的调用栈;二是记录与所关注的变量存在数据写依赖的变量的信息,即计算当前线程的调用栈栈顶的变量地址列表与前述变量列表variablelist的交集a,记录a中所有的变量及其当前值;三是记录与所关注的变量存在数据写依赖的其他线程及其变量信息,即计算所有其他线程的调用栈栈顶的变量地址列表与前述变量列表variablelist的交集b,若b不为空,则记录该线程的调用栈,记录b中所有的变量及其当前值;如果b为空则不记录该线程的调用栈。
[0047]
s4.4、设置处理器的异常处理标志为继续执行,lldb解析被调试程序的调试信息,计算当前断点指令地址之后的下一行代码的指令地址,处理器根据该指令地址执行下一条指令。
[0048]
s5、使用lldb启动被调试程序,循环执行代码,迭代次数达到设定值退出;或产生异常,异常可为普通异常,也可以是目标变量超出了设定的取值范围,结束测试。
[0049]
s6、每次命中断点时的信息存储过程为:s6.1、存储各类信息实体,包括线程、栈顶函数、变量三类,表示为[time, id, type, name, property];当新实体到来时,查询是否已存在,不存在则加入,且记录加入断点时间;s6.2、存储信息实体之间的关系,包括线程拥有的栈顶函数、栈顶函数拥有的变量、变量与变量的依赖关系三类关系,以断点时间为唯一索引建立[time, id1, id2]、[time, threadid, functionid]、[time, functionid,varid]及[time, varid,varid],此外,由于变量在使用期间名称不会变化,所以为减小存储空间,变量只存储值的变化,以断点时间作为索引:[time, varid, value];s6.3、每次命中断点时,仅记录发生变化的线程的相关内容,未发生变化的内容不再重复记录,后续查询时采用最接近断点时间的数据代替。
[0050]
s7、断点历史数据检索过程:s7.1、按照时间点查询:以输入的时间点为条件查询数据,查询该时间已存在的实体及其关系;当实体存在而该时间点的关系数据不存在时,查询包含该实体且与与该时间点最接近的前一个断点时间点的关系数据;s7.2、按照变量查询:查询到变量的首次和末次出现的时间点,按照步骤7.1,依次查询各时间点的数据;s7.3、按照线程查询:查询到线程的首次和末次出现的时间点,按照步骤7.1,依次查询各时间点的数据。
[0051]
综上所述,以上仅为本发明的较佳实施例而已,并非用于限定本发明的保护范围。凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1