用于调试目标程序代码的方法及装置、电子设备转让专利

申请号 : CN202111631234.2

文献号 : CN113986771B

文献日 :

基本信息:

PDF:

法律信息:

相似专利:

发明人 : 不公告发明人

申请人 : 北京壁仞科技开发有限公司上海壁仞智能科技有限公司

摘要 :

一种用于调试目标程序代码的方法及装置、电子设备。该方法包括:调试主程序获取调试过程代码,调试过程代码包括目标程序代码以及插入到目标程序代码中至少一个调试位置的至少一个调试指令;将调试过程代码以及调试辅助程序上载至协处理器,且使协处理器执行调试过程代码;在协处理器运行调试过程代码的过程中,响应于执行至少一个调试指令,从调试过程代码跳转以使协处理器执行调试辅助程序,并由调试辅助程序返回调试过程代码当前的运行状态信息。该方法可以实现图形处理器的程序调试,无需使用硬件中断指令,对图形处理器的硬件条件要求低,不依赖特定硬件指令的支持,适用范围广。

权利要求 :

1.一种用于调试由协处理器执行的目标程序代码的方法,包括:调试主程序获取调试过程代码,其中,所述调试过程代码包括所述目标程序代码以及插入到所述目标程序代码中至少一个调试位置的至少一个调试指令,所述调试主程序运行在主处理器中,所述主处理器不同于所述协处理器;

将所述调试过程代码以及调试辅助程序上载至所述协处理器,且使所述协处理器执行所述调试过程代码;

在所述协处理器运行所述调试过程代码的过程中,响应于执行所述至少一个调试指令,从所述调试过程代码跳转以使所述协处理器执行所述调试辅助程序,并由所述调试辅助程序返回所述调试过程代码当前的运行状态信息;

其中,所述方法还包括:

所述调试辅助程序向所述调试主程序发送第一通知信息,并基于轮询机制等待获取由所述调试主程序发送的第二通知信息,其中,所述第一通知信息表示所述至少一个调试指令被执行,所述第二通知信息表示所述调试主程序响应了所述第一通知信息;

其中,在调试由所述协处理器执行的所述目标程序代码的过程中,所述协处理器不使用硬件中断指令。

2.根据权利要求1所述的方法,还包括:所述调试主程序基于所述轮询机制查询获取由所述调试辅助程序发送的所述第一通知信息。

3.根据权利要求2所述的方法,其中,所述协处理器包括存储空间,所述存储空间配置为可以从所述协处理器外部和所述协处理器内部进行访问,所述调试辅助程序向所述调试主程序发送所述第一通知信息,并基于所述轮询机制等待获取由所述调试主程序发送的所述第二通知信息,包括:所述调试辅助程序将存储在所述存储空间中的第一信号位设置为有效值;

所述调试辅助程序轮询存储在所述存储空间中的第二信号位并判断所述第二信号位是否为有效值,响应于所述第二信号位为有效值,确定获取到所述第二通知信息。

4.根据权利要求3所述的方法,其中,所述调试主程序基于所述轮询机制查询获取由所述调试辅助程序发送的所述第一通知信息,包括:所述调试主程序轮询所述第一信号位,并判断所述第一信号位是否为有效值,响应于所述第一信号位为有效值,确定获取到所述第一通知信息。

5.根据权利要求4所述的方法,其中,由所述调试辅助程序返回所述调试过程代码当前的运行状态信息,包括:

所述调试辅助程序将所述调试过程代码当前的运行状态信息存储在所述存储空间中。

6.根据权利要求5所述的方法,还包括:响应于获取到所述第一通知信息,所述调试主程序访问所述存储空间以获取所述运行状态信息,并将所述第一信号位设置为无效值。

7.根据权利要求6所述的方法,还包括:基于所述运行状态信息,所述调试主程序执行打印操作和/或接收指令操作。

8.根据权利要求7所述的方法,其中,所述调试位置表示调试过程代码的断点,基于所述运行状态信息,所述调试主程序执行所述打印操作和/或所述接收指令操作,包括:

判断所述调试指令所在的调试位置表示的断点是否命中;

响应于所述断点命中,接收用户输入的指令以作为待执行指令;

响应于所述断点未命中,将继续执行指令设置为所述待执行指令;

响应于所述待执行指令为打印指令,根据标准调试文件打印所述运行状态信息后继续接收所述用户输入的指令;

响应于所述待执行指令不是所述打印指令,将所述待执行指令存入所述存储空间后向所述调试辅助程序发送所述第二通知信息。

9.根据权利要求8所述的方法,其中,判断所述调试指令所在的调试位置表示的断点是否命中,包括:

响应于所述断点处于启用状态且不是条件断点,确定所述断点命中;

响应于所述断点处于所述启用状态且是所述条件断点,并且所述条件断点对应的条件成就,确定所述断点命中。

10.根据权利要求8所述的方法,其中,向所述调试辅助程序发送所述第二通知信息,包括:

所述调试主程序将存储在所述存储空间中的所述第二信号位设置为有效值。

11.根据权利要求10所述的方法,还包括:响应于获取到所述第二通知信息,所述调试辅助程序访问所述存储空间以获取所述待执行指令,并将所述第二信号位设置为无效值。

12.根据权利要求11所述的方法,还包括:根据所述待执行指令的类型,确定是否从所述调试辅助程序跳转以使所述协处理器恢复执行所述调试过程代码。

13.根据权利要求12所述的方法,其中,根据所述待执行指令的类型,确定是否从所述调试辅助程序跳转以使所述协处理器恢复执行所述调试过程代码,包括:响应于所述待执行指令为所述继续执行指令或单步执行指令,从所述调试辅助程序跳转至所述调试过程代码,并向所述调试主程序发送第三通知信息,其中,所述第三通知信息表示所述调试辅助程序响应了所述待执行指令;

响应于所述待执行指令不是所述继续执行指令且不是所述单步执行指令,执行所述待执行指令后向所述调试主程序发送所述第三通知信息,并基于所述轮询机制获取由所述调试主程序发送的所述第二通知信息。

14.根据权利要求13所述的方法,其中,向所述调试主程序发送所述第三通知信息,包括:

所述调试辅助程序将存储在所述存储空间中的第三信号位设置为有效值。

15.根据权利要求14所述的方法,还包括:所述调试主程序基于所述轮询机制查询获取由所述调试辅助程序发送的所述第三通知信息。

16.根据权利要求15所述的方法,其中,所述调试主程序基于所述轮询机制查询获取由所述调试辅助程序发送的所述第三通知信息,包括:所述调试主程序轮询所述第三信号位,并判断所述第三信号位是否为有效值,响应于所述第三信号位为有效值,确定获取到所述第三通知信息。

17.根据权利要求16所述的方法,还包括:响应于获取到所述第三通知信息,根据所述待执行指令的类型,确定所述调试主程序的执行分支。

18.根据权利要求17所述的方法,其中,根据所述待执行指令的类型,确定所述调试主程序的执行分支,包括:

判断所述待执行指令是否为所述继续执行指令或所述单步执行指令;

响应于所述待执行指令是所述继续执行指令或所述单步执行指令,基于所述轮询机制获取由所述调试辅助程序发送的所述第一通知信息;

响应于所述待执行指令不是所述继续执行指令且不是所述单步执行指令,继续接收所述用户输入的指令。

19.根据权利要求1‑18任一所述的方法,还包括:响应于用户输入的指令为单步执行指令,基于标准调试文件,以所述目标程序代码中对应于目标程序下一行语句的代码处作为所述调试位置,插入所述调试指令,其中,所述调试位置表示的断点默认为启用状态。

20.根据权利要求1‑18任一所述的方法,还包括:以所述目标程序代码中对应于目标程序每一行语句的代码处作为所述调试位置,插入所述调试指令,并且根据预设状态表设置各个调试位置表示的断点是否为启用状态。

21.根据权利要求20所述的方法,其中,所述预设状态表记录各个调试位置表示的断点的状态,需要进行调试的调试位置表示的断点为启用状态。

22.根据权利要求20所述的方法,还包括:响应于用户输入的指令为单步执行指令,基于标准调试文件,将所述目标程序代码中对应于所述目标程序下一行语句的代码处所对应的调试位置表示的断点更新为启用状态。

23.根据权利要求1‑18任一所述的方法,其中,所述协处理器包括图形处理器和/或通用图形处理器。

24.一种用于调试由协处理器执行的目标程序代码的方法,用于运行在主处理器中的系统侧,所述主处理器不同于所述协处理器,其中,所述方法包括:获取调试过程代码,其中,所述调试过程代码包括所述目标程序代码以及插入到所述目标程序代码中至少一个调试位置的至少一个调试指令;

将所述调试过程代码以及调试辅助程序上载至所述协处理器,从而使所述协处理器执行所述调试过程代码;

获取所述调试辅助程序返回的所述调试过程代码当前的运行状态信息,其中,所述协处理器运行所述调试过程代码的过程中,响应于执行所述至少一个调试指令,从所述调试过程代码跳转以执行所述调试辅助程序;

其中,所述方法还包括:

运行在所述主处理器中的调试主程序基于轮询机制等待获取由所述调试辅助程序发送的第一通知信息,并发送第二通知信息,其中,所述第一通知信息表示所述至少一个调试指令被执行,所述第二通知信息表示所述调试主程序响应了所述第一通知信息;

其中,在调试由所述协处理器执行的所述目标程序代码的过程中,所述协处理器不使用硬件中断指令。

25.一种用于调试由协处理器执行的目标程序代码的方法,用于所述协处理器,包括:接收调试过程代码,其中,所述调试过程代码包括所述目标程序代码以及插入到所述目标程序代码中至少一个调试位置的至少一个调试指令,所述调试过程代码由运行在主处理器中的调试主程序发送,所述主处理器不同于所述协处理器;

接收调试辅助程序;

运行所述调试过程代码,响应于执行所述至少一个调试指令,从所述调试过程代码跳转以执行所述调试辅助程序,并由所述调试辅助程序返回所述调试过程代码当前的运行状态信息;

其中,所述方法还包括:

所述调试辅助程序向所述调试主程序发送第一通知信息,并基于轮询机制等待获取由所述调试主程序发送的第二通知信息,其中,所述第一通知信息表示所述至少一个调试指令被执行,所述第二通知信息表示所述调试主程序响应了所述第一通知信息;

其中,在调试由所述协处理器执行的所述目标程序代码的过程中,所述协处理器不使用硬件中断指令。

26.一种用于调试由协处理器执行的目标程序代码的装置,包括:代码获取单元,配置为由调试主程序获取调试过程代码,其中,所述调试过程代码包括所述目标程序代码以及插入到所述目标程序代码中至少一个调试位置的至少一个调试指令,所述调试主程序运行在主处理器中,所述主处理器不同于所述协处理器;

上载单元,配置为将所述调试过程代码以及调试辅助程序上载至所述协处理器;

调试辅助单元,配置为在所述协处理器执行所述调试过程代码的过程中,响应于执行所述至少一个调试指令,从所述调试过程代码跳转,并返回所述调试过程代码当前的运行状态信息;

其中,所述调试辅助单元还配置为:由所述调试辅助程序向所述调试主程序发送第一通知信息,并基于轮询机制等待获取由所述调试主程序发送的第二通知信息,其中,所述第一通知信息表示所述至少一个调试指令被执行,所述第二通知信息表示所述调试主程序响应了所述第一通知信息;

其中,在调试由所述协处理器执行的所述目标程序代码的过程中,所述协处理器不使用硬件中断指令。

27.一种电子设备,包括根据权利要求26所述的用于调试由协处理器执行的目标程序代码的装置。

说明书 :

用于调试目标程序代码的方法及装置、电子设备

技术领域

[0001] 本公开的实施例涉及一种用于调试由协处理器执行的目标程序代码的方法及装置、电子设备。

背景技术

[0002] 在计算机技术领域及芯片技术领域,通常采用调试程序(Debugger程序)来进行调试。Debugger程序是一种调试工具,可以供程序开发人员检查修改程序问题。通常的操作系
统会提供Debugger程序,Debugger程序通过提供逐条执行代码、设置程序断点以及检查断
点处变量和内存等功能,帮助程序开发人员跟踪代码运行流程,定位程序异常点。

发明内容

[0003] 本公开至少一个实施例提供一种用于调试由协处理器执行的目标程序代码的方法,包括:调试主程序获取调试过程代码,其中,所述调试过程代码包括所述目标程序代码
以及插入到所述目标程序代码中至少一个调试位置的至少一个调试指令;将所述调试过程
代码以及调试辅助程序上载至所述协处理器,且使所述协处理器执行所述调试过程代码;
在所述协处理器运行所述调试过程代码的过程中,响应于执行所述至少一个调试指令,从
所述调试过程代码跳转以使所述协处理器执行所述调试辅助程序,并由所述调试辅助程序
返回所述调试过程代码当前的运行状态信息。
[0004] 例如,本公开一实施例提供的方法还包括:所述调试辅助程序向所述调试主程序发送第一通知信息,并基于轮询机制等待获取由所述调试主程序发送的第二通知信息,其
中,所述第一通知信息表示所述至少一个调试指令被执行,所述第二通知信息表示所述调
试主程序响应了所述第一通知信息。
[0005] 例如,本公开一实施例提供的方法还包括:所述调试主程序基于所述轮询机制查询获取由所述调试辅助程序发送的所述第一通知信息。
[0006] 例如,在本公开一实施例提供的方法中,所述协处理器包括存储空间,所述存储空间配置为可以从所述协处理器外部和所述协处理器内部进行访问,所述调试辅助程序向所
述调试主程序发送所述第一通知信息,并基于所述轮询机制等待获取由所述调试主程序发
送的所述第二通知信息,包括:所述调试辅助程序将存储在所述存储空间中的第一信号位
设置为有效值;所述调试辅助程序轮询存储在所述存储空间中的第二信号位并判断所述第
二信号位是否为有效值,响应于所述第二信号位为有效值,确定获取到所述第二通知信息。
[0007] 例如,在本公开一实施例提供的方法中,所述调试主程序基于所述轮询机制查询获取由所述调试辅助程序发送的所述第一通知信息,包括:所述调试主程序轮询所述第一
信号位,并判断所述第一信号位是否为有效值,响应于所述第一信号位为有效值,确定获取
到所述第一通知信息。
[0008] 例如,在本公开一实施例提供的方法中,由所述调试辅助程序返回所述调试过程代码当前的运行状态信息,包括:所述调试辅助程序将所述调试过程代码当前的运行状态
信息存储在所述存储空间中。
[0009] 例如,本公开一实施例提供的方法还包括:响应于获取到所述第一通知信息,所述调试主程序访问所述存储空间以获取所述运行状态信息,并将所述第一信号位设置为无效
值。
[0010] 例如,本公开一实施例提供的方法还包括:基于所述运行状态信息,所述调试主程序执行打印操作和/或接收指令操作。
[0011] 例如,在本公开一实施例提供的方法中,所述调试位置表示调试过程代码的断点,基于所述运行状态信息,所述调试主程序执行所述打印操作和/或所述接收指令操作,包
括:判断所述调试指令所在的调试位置表示的断点是否命中;响应于所述断点命中,接收用
户输入的指令以作为待执行指令;响应于所述断点未命中,将继续执行指令设置为所述待
执行指令;响应于所述待执行指令为打印指令,根据标准调试文件打印所述运行状态信息
后继续接收所述用户输入的指令;响应于所述待执行指令不是所述打印指令,将所述待执
行指令存入所述存储空间后向所述调试辅助程序发送所述第二通知信息。
[0012] 例如,在本公开一实施例提供的方法中,判断所述调试指令所在的调试位置表示的断点是否命中,包括:响应于所述断点处于启用状态且不是条件断点,确定所述断点命
中;响应于所述断点处于所述启用状态且是所述条件断点,并且所述条件断点对应的条件
成就,确定所述断点命中。
[0013] 例如,在本公开一实施例提供的方法中,向所述调试辅助程序发送所述第二通知信息,包括:所述调试主程序将存储在所述存储空间中的所述第二信号位设置为有效值。
[0014] 例如,本公开一实施例提供的方法还包括:响应于获取到所述第二通知信息,所述调试辅助程序访问所述存储空间以获取所述待执行指令,并将所述第二信号位设置为无效
值。
[0015] 例如,本公开一实施例提供的方法还包括:根据所述待执行指令的类型,确定是否从所述调试辅助程序跳转以使所述协处理器恢复执行所述调试过程代码。
[0016] 例如,在本公开一实施例提供的方法中,根据所述待执行指令的类型,确定是否从所述调试辅助程序跳转以使所述协处理器恢复执行所述调试过程代码,包括:响应于所述
待执行指令为所述继续执行指令或单步执行指令,从所述调试辅助程序跳转至所述调试过
程代码,并向所述调试主程序发送第三通知信息,其中,所述第三通知信息表示所述调试辅
助程序响应了所述待执行指令;响应于所述待执行指令不是所述继续执行指令且不是所述
单步执行指令,执行所述待执行指令后向所述调试主程序发送所述第三通知信息,并基于
所述轮询机制获取由所述调试主程序发送的所述第二通知信息。
[0017] 例如,在本公开一实施例提供的方法中,向所述调试主程序发送所述第三通知信息,包括:所述调试辅助程序将存储在所述存储空间中的第三信号位设置为有效值。
[0018] 例如,本公开一实施例提供的方法还包括:所述调试主程序基于所述轮询机制查询获取由所述调试辅助程序发送的所述第三通知信息。
[0019] 例如,在本公开一实施例提供的方法中,所述调试主程序基于所述轮询机制查询获取由所述调试辅助程序发送的所述第三通知信息,包括:所述调试主程序轮询所述第三
信号位,并判断所述第三信号位是否为有效值,响应于所述第三信号位为有效值,确定获取
到所述第三通知信息。
[0020] 例如,本公开一实施例提供的方法还包括:响应于获取到所述第三通知信息,根据所述待执行指令的类型,确定所述调试主程序的执行分支。
[0021] 例如,在本公开一实施例提供的方法中,根据所述待执行指令的类型,确定所述调试主程序的执行分支,包括:判断所述待执行指令是否为所述继续执行指令或所述单步执
行指令;响应于所述待执行指令是所述继续执行指令或所述单步执行指令,基于所述轮询
机制获取由所述调试辅助程序发送的所述第一通知信息;响应于所述待执行指令不是所述
继续执行指令且不是所述单步执行指令,继续接收所述用户输入的指令。
[0022] 例如,本公开一实施例提供的方法还包括:响应于用户输入的指令为单步执行指令,基于标准调试文件,以所述目标程序代码中对应于目标程序下一行语句的代码处作为
所述调试位置,插入所述调试指令,其中,所述调试位置表示的断点默认为启用状态。
[0023] 例如,本公开一实施例提供的方法还包括:以所述目标程序代码中对应于目标程序每一行语句的代码处作为所述调试位置,插入所述调试指令,并且根据预设状态表设置
各个调试位置表示的断点是否为启用状态。
[0024] 例如,在本公开一实施例提供的方法中,所述预设状态表记录各个调试位置表示的断点的状态,需要进行调试的调试位置表示的断点为启用状态。
[0025] 例如,本公开一实施例提供的方法还包括:响应于用户输入的指令为单步执行指令,基于标准调试文件,将所述目标程序代码中对应于所述目标程序下一行语句的代码处
所对应的调试位置表示的断点更新为启用状态。
[0026] 例如,在本公开一实施例提供的方法中,所述协处理器包括图形处理器和/或通用图形处理器。
[0027] 本公开至少一个实施例还提供一种用于调试由协处理器执行的目标程序代码的方法,用于系统侧,包括:获取调试过程代码,其中,所述调试过程代码包括所述目标程序代
码以及插入到所述目标程序代码中至少一个调试位置的至少一个调试指令;将所述调试过
程代码以及调试辅助程序上载至所述协处理器,从而使所述协处理器执行所述调试过程代
码;获取所述调试辅助程序返回的所述调试过程代码当前的运行状态信息,其中,所述协处
理器运行所述调试过程代码的过程中,响应于执行所述至少一个调试指令,从所述调试过
程代码跳转以执行所述调试辅助程序。
[0028] 本公开至少一个实施例还提供一种用于调试由协处理器执行的目标程序代码的方法,用于所述协处理器,包括:接收调试过程代码,其中,所述调试过程代码包括所述目标
程序代码以及插入到所述目标程序代码中至少一个调试位置的至少一个调试指令;接收调
试辅助程序;运行所述调试过程代码,响应于执行所述至少一个调试指令,从所述调试过程
代码跳转以执行所述调试辅助程序,并由所述调试辅助程序返回所述调试过程代码当前的
运行状态信息。
[0029] 本公开至少一个实施例还提供一种用于调试由协处理器执行的目标程序代码的装置,包括:代码获取单元,配置为获取调试过程代码,其中,所述调试过程代码包括所述目
标程序代码以及插入到所述目标程序代码中至少一个调试位置的至少一个调试指令;上载
单元,配置为将所述调试过程代码以及调试辅助程序上载至所述协处理器;调试辅助单元,
配置为在所述协处理器执行所述调试过程代码的过程中,响应于执行所述至少一个调试指
令,从所述调试过程代码跳转,并返回所述调试过程代码当前的运行状态信息。
[0030] 本公开至少一个实施例还提供一种电子设备,包括根据本公开任一实施例提供的用于调试由协处理器执行的目标程序代码的装置。

附图说明

[0031] 为了更清楚地说明本公开实施例的技术方案,下面将对实施例的附图作简单地介绍,显而易见地,下面描述中的附图仅仅涉及本公开的一些实施例,而非对本公开的限制。
[0032] 图1为本公开一些实施例提供的一种电子设备的示意框图;
[0033] 图2为本公开一些实施例提供的一种用于调试由协处理器执行的目标程序代码的方法的流程示意图;
[0034] 图3为本公开一些实施例提供的另一种用于调试由协处理器执行的目标程序代码的方法的流程示意图;
[0035] 图4为图3中步骤S14的示例性流程图;
[0036] 图5为图3中步骤S17的示例性流程图;
[0037] 图6为图3中步骤S19的示例性流程图;
[0038] 图7为图3中步骤S21的示例性流程图;
[0039] 图8为本公开一些实施例提供的另一种用于调试由协处理器执行的目标程序代码的方法的流程示意图;
[0040] 图9为本公开一些实施例提供的一种用于调试由协处理器执行的目标程序代码的方法的工作流程图之一;
[0041] 图10为本公开一些实施例提供的一种用于调试由协处理器执行的目标程序代码的方法的工作流程图之二;
[0042] 图11为本公开一些实施例提供的一种用于调试由协处理器执行的目标程序代码的方法的流程示意图;
[0043] 图12为本公开一些实施例提供的另一种用于调试由协处理器执行的目标程序代码的方法的流程示意图;
[0044] 图13为本公开一些实施例提供的一种用于调试由协处理器执行的目标程序代码的装置的示意框图;
[0045] 图14为本公开一些实施例提供的一种电子设备的示意框图。

具体实施方式

[0046] 为使本公开实施例的目的、技术方案和优点更加清楚,下面将结合本公开实施例的附图,对本公开实施例的技术方案进行清楚、完整地描述。显然,所描述的实施例是本公
开的一部分实施例,而不是全部的实施例。基于所描述的本公开的实施例,本领域普通技术
人员在无需创造性劳动的前提下所获得的所有其他实施例,都属于本公开保护的范围。
[0047] 除非另外定义,本公开使用的技术术语或者科学术语应当为本公开所属领域内具有一般技能的人士所理解的通常意义。本公开中使用的“第一”、“第二”以及类似的词语并
不表示任何顺序、数量或者重要性,而只是用来区分不同的组成部分。同样,“一个”、“一”或
者“该”等类似词语也不表示数量限制,而是表示存在至少一个。“包括”或者“包含”等类似
的词语意指出现该词前面的元件或者物件涵盖出现在该词后面列举的元件或者物件及其
等同,而不排除其他元件或者物件。“连接”或者“相连”等类似的词语并非限定于物理的或
者机械的连接,而是可以包括电性的连接,不管是直接的还是间接的。“上”、“下”、“左”、
“右”等仅用于表示相对位置关系,当被描述对象的绝对位置改变后,则该相对位置关系也
可能相应地改变。
[0048] 在计算机系统中,Trap指令是中央处理器(Central Processing Unit,CPU)、图形处理器(Graphics Processing Unit,GPU)等提供的用于处理意外情况的一类硬件指令,
Trap指令可以暂停当前用户程序并转入相应的异常处理程序。利用Debugger程序实现调试
通常需要硬件Trap指令和操作系统的支持。
[0049] 例如,在X86架构的处理器中,GDB(X86提供的一种调试程序)的实现利用了硬件提供的INT 3指令和Linux提供的Ptrace系统调用。Debugger程序作为父进程可以通过Ptrace
跟踪和控制子进程(也即用户程序)的执行,并且检查和更改子进程内存和寄存器值。例如,
Debugger程序首先把需要设置断点的位置处的指令替换为INT 3指令,然后运行子进程,当
子进程执行到INT 3指令后会触发中断,操作系统内核暂停子进程并发送SIGTRAP信号。
Debugger程序截获该信号并判断是否断点命中,如果命中,则恢复被替换的指令并等待用
户输入,此时便可以通过Ptrace提供的一系列请求方法检查或更改断点处的实时环境,最
后通过Ptrace恢复子进程的运行。INT 3指令也属于Trap指令,是一种硬件指令。一些GPU也
提供了类似INT 3的Trap指令,可以暂停内核代码的运行并触发系统侧(Host侧)的中断。
[0050] 针对利用GPU运行程序的应用场景,通常的Debugger程序都依赖于硬件指令的支持。如果GPU硬件架构本身缺少Trap指令,则难以进行调试。这对GPU的硬件架构提出了更高
的要求,过度依赖硬件指令,增加了实现调试的难度。
[0051] 本公开至少一个实施例提供一种用于调试由协处理器执行的目标程序代码的方法及装置、电子设备。该方法可以实现图形处理器的程序调试,无需使用硬件中断指令,对
图形处理器的硬件条件要求低,不依赖特定硬件指令的支持,适用范围广。
[0052] 下面,将参考附图详细地说明本公开的实施例。应当注意的是,不同的附图中相同的附图标记将用于指代已描述的相同的元件。
[0053] 本公开至少一个实施例提供一种用于调试由协处理器执行的目标程序代码的方法。该方法包括:调试主程序获取调试过程代码,调试过程代码包括目标程序代码以及插入
到目标程序代码中至少一个调试位置的至少一个调试指令;将调试过程代码以及调试辅助
程序上载至协处理器,且使协处理器执行调试过程代码;在协处理器运行调试过程代码的
过程中,响应于执行至少一个调试指令,从调试过程代码跳转以使协处理器执行调试辅助
程序,并由调试辅助程序返回调试过程代码当前的运行状态信息。
[0054] 图1为本公开一些实施例提供的一种电子设备的示意框图,本公开实施例提供的用于调试由协处理器执行的目标程序代码的方法适用于该电子设备。如图1所示,该电子设
备包括主处理器110和协处理器120,主处理器110与协处理器120通信连接。例如,主处理器
110可以为CPU,该电子设备的操作系统以及主要的程序进程运行在主处理器110中。例如,
协处理器120可以为GPU,协处理器120加载来自主处理器110的程序并运行,同时将运行结
果返回给主处理器110。例如,协处理器120可以作为主处理器110的加速单元,或者作为由
主处理器110管理的专用计算单元,或者还可以起到其他适用的功能和作用,本公开的实施
例对此不作限制。例如,协处理器120不限于为GPU,还可以为其他任意适用的具有运算能力
的装置,例如通用图形处理器(General‑purpose Computing on Graphics Processing 
Unit,GPGPU)等,这可以根据实际需求而定,本公开的实施例对此不作限制。
[0055] 例如,主处理器110包括代码获取单元111和上载单元112,协处理器120包括调试辅助单元121。关于代码获取单元111、上载单元112、调试辅助单元121的功能,将在后文结
合本公开实施例提供的用于调试由协处理器执行的目标程序代码的方法进行详细说明,此
处不再赘述。
[0056] 图2为本公开一些实施例提供的一种用于调试由协处理器执行的目标程序代码的方法的流程示意图。如图2所示,在一些实施例中,该方法包括如下操作。
[0057] 步骤S11:调试主程序获取调试过程代码,其中,调试过程代码包括目标程序代码以及插入到目标程序代码中至少一个调试位置的至少一个调试指令;
[0058] 步骤S12:将调试过程代码以及调试辅助程序上载至协处理器,且使协处理器执行调试过程代码;
[0059] 步骤S13:在协处理器运行调试过程代码的过程中,响应于执行至少一个调试指令,从调试过程代码跳转以使协处理器执行调试辅助程序,并由调试辅助程序返回调试过
程代码当前的运行状态信息。
[0060] 例如,在步骤S11中,调试主程序运行在主处理器110中,也即是,运行在CPU的系统侧(Host侧)。例如,调试主程序可以是在前述的Debugger程序的基础上进行调整而得到的
程序,调试主程序可以利用操作系统提供的与Debugger有关的功能接口,从而提供调试功
能。
[0061] 调试过程代码包括目标程序代码以及插入到目标程序代码中至少一个调试位置的至少一个调试指令。目标程序代码例如是需要进行调试的程序的可执行二进制文件(例
如ELF文件)。为了实现调试,需要提前在目标程序代码中至少一个调试位置插入至少一个
调试指令。例如,调试位置表示调试过程代码的断点,根据程序开发人员的需要而确定,调
试位置可以为目标程序代码中的任意位置。调试指令可以被称为Call Trap Handler指令,
用于在执行时使进程跳转。例如,调试指令的类型可以是Call指令、branch指令,或者也可
以是其他类型的能够实现进程跳转的指令,本公开的实施例对此不作限制。例如,调试指令
可以与通常的计算机系统中的Trap指令不同。
[0062] 例如,步骤S11可以由图1中的代码获取单元111执行,代码获取单元111可以运行调试主程序并利用调试主程序获取调试过程代码。
[0063] 例如,在步骤S12中,将调试过程代码以及调试辅助程序均从主处理器110上载至协处理器120,由此使协处理器120执行调试过程代码。调试辅助程序也可以称为Trap 
handler,用于在协处理器120中被调用以帮助实现程序调试。例如,调试过程代码被上载至
协处理器120之后便开始执行,而调试辅助程序被上载至协处理器120之后并不直接开始执
行,而是处于等待状态。例如,将调试过程代码以及调试辅助程序上载至协处理器120的方
式可以采用通常的CPU与GPU之间的加载方式,此处不再详述。
[0064] 例如,步骤S12可以由图1中的上载单元112执行,上载单元112可以将调试过程代码以及调试辅助程序均从主处理器110上载至协处理器120。
[0065] 例如,在步骤S13中,在协处理器120运行调试过程代码的过程中,若执行到调试指令,则会从调试过程代码跳转至调试辅助程序,并开始执行调试辅助程序。通过执行调试辅
助程序,由调试辅助程序返回调试过程代码当前的运行状态信息。例如,调试辅助程序开始
执行后,会与运行在主处理器110中的调试主程序交互,通过调试辅助程序与调试主程序之
间的配合与交互,从而可以使调试主程序获取调试过程代码当前的运行状态信息(例如内
存和寄存器值等),并且实现调试功能。
[0066] 例如,步骤S13可以由图1中的调试辅助单元121执行,调试辅助单元121可以响应于执行调试指令而跳转以执行调试辅助程序,并返回调试过程代码当前的运行状态信息。
[0067] 在本公开的实施例中,通过设置调试指令(该调试指令并非Trap指令)并且采用调试辅助程序,利用软件中断的方式实现图形处理器(GPU)和/或通用图形处理器(GPGPU)的
程序调试,而无需使用硬件中断指令(例如Trap指令)。这对GPU/GPGPU的硬件条件要求低,
不依赖特定硬件指令的支持,适用范围广。即使在GPU/GPGPU架构缺少Trap指令的情况下,
本公开实施例提供的方法仍然能够实现GPU/GPGPU的程序调试,为GPU/GPGPU程序的开发与
调试提供了极大的便利。
[0068] 图3为本公开一些实施例提供的另一种用于调试由协处理器执行的目标程序代码的方法的流程示意图。如图3所示,在一些示例中,除了包括步骤S11‑S13,该方法还可以进
一步包括步骤S14‑S21。例如,图3中的步骤S11‑S13与图2中的步骤S11‑S13基本相同,此处
不再赘述。
[0069] 步骤S14:调试辅助程序向调试主程序发送第一通知信息,并基于轮询机制等待获取由调试主程序发送的第二通知信息;
[0070] 步骤S15:调试主程序基于轮询机制查询获取由调试辅助程序发送的第一通知信息;
[0071] 步骤S16:响应于获取到第一通知信息,调试主程序访问存储空间以获取运行状态信息,并将第一信号位设置为无效值;
[0072] 步骤S17:基于运行状态信息,调试主程序执行打印操作和/或接收指令操作;
[0073] 步骤S18:响应于获取到第二通知信息,调试辅助程序访问存储空间以获取待执行指令,并将第二信号位设置为无效值;
[0074] 步骤S19:根据待执行指令的类型,确定是否从调试辅助程序跳转以使协处理器恢复执行调试过程代码;
[0075] 步骤S20:调试主程序基于轮询机制查询获取由调试辅助程序发送的第三通知信息;
[0076] 步骤S21:响应于获取到第三通知信息,根据待执行指令的类型,确定调试主程序的执行分支。
[0077] 例如,在步骤S14中,当协处理器120运行调试过程代码并执行到调试指令时,会从调试过程代码跳转至调试辅助程序,并开始执行调试辅助程序,调制辅助程序开始执行时
会向调试主程序发送第一通知信息。该第一通知信息表示至少一个调试指令被执行,也即,
通过第一通知信息告知调试主程序在协处理器120中运行的调试过程代码已经执行到调试
指令,并且跳转至调试辅助程序。
[0078] 例如,调试辅助程序还基于轮询机制等待获取由调试主程序发送的第二通知信息,该第二通知信息表示调试主程序响应了第一通知信息。如果调试辅助程序没有获取到
第二通知信息,则会一直基于轮询机制等待接收第二通知信息;如果调试辅助程序获取到
第二通知信息,则会进行后续操作。通过这种方式,可以使调试辅助程序陷入循环,从而暂
停调试过程代码的执行。
[0079] 例如,协处理器120可以包括存储空间,该存储空间配置为可以从协处理器120外部和协处理器120内部进行访问。例如,可以在协处理器120内部访问该存储空间,也可以从
系统侧的主处理器110访问该存储空间。例如,在一些示例中,该存储空间可以为设置在协
处理器120中的内存,例如高带宽内存(High Bandwidth Memory,HBM),该高带宽内存可以
在协处理器120中访问,也可以从系统侧的主处理器110访问。当然,本公开的实施例不限于
此,存储空间可以为任意适用的存储装置,不限于HBM,这可以根据实际需求而定,本公开的
实施例对此不作限制。
[0080] 例如,如图5所示,在协处理器120中设置有存储空间的情形下,上述步骤S14可以进一步包括如下操作。
[0081] 步骤S141:调试辅助程序将存储在存储空间中的第一信号位设置为有效值;
[0082] 步骤S142:调试辅助程序轮询存储在存储空间中的第二信号位并判断第二信号位是否为有效值,响应于第二信号位为有效值,确定获取到第二通知信息。
[0083] 例如,可以在存储空间中存储多个信号位(例如第一信号位和第二信号位),这些信号位可以设置为有效值,也可以设置为无效值,从而实现状态的变更,以达到传递信息的
目的。例如,在一些示例中,第一信号位和第二信号位可以分别为1位二进制数,“1”为有效
值,“0”为无效值。当然,本公开的实施例不限于此,可以采用任意的数据类型和数据位数来
表示信号位,这可以根据实际需求而定。
[0084] 例如,在步骤S141中,协处理器120中的调试辅助程序将存储在存储空间中的第一信号位设置为有效值,从而便于主处理器110中的调试主程序查询,以达到传递第一通知信
息的目的。
[0085] 例如,在步骤S142中,调试辅助程序轮询存储在存储空间中的第二信号位并判断第二信号位是否为有效值,若第二信号位为有效值,则确定获取到第二通知信息。例如,在
一定条件下,主处理器110中的调试主程序会将存储空间中的第二信号位设置为有效值,从
而便于协处理器120中的调试辅助程序查询,以达到传递第二通知信息的目的。关于传递第
二通知信息的相关说明,将在后文描述,此处不再赘述。
[0086] 例如,在协处理器120中设置有存储空间的情形下,在步骤S13中,由调试辅助程序返回调试过程代码当前的运行状态信息可以包括:调试辅助程序将调试过程代码当前的运
行状态信息存储在存储空间中。例如,运行状态信息可以包括协处理器120中的寄存器值和
栈内容,这些寄存器值和栈内容可以反映调试过程代码的当前运行状态,程序开发人员可
以根据这些寄存器值和栈内容判断程序是否需要修改以及如何修改,从而实现程序调试。
需要说明的是,运行状态信息不限于为寄存器值和栈内容,还可以为任意的需要使用的、可
以反映代码运行状态的信息,本公开的实施例对此不作限制。
[0087] 返回至图4,在步骤S15中,在将调试过程代码以及调试辅助程序从主处理器110上载至协处理器120之后,调试主程序会开始基于轮询机制查询获取由调试辅助程序发送的
第一通知信息。例如,在一些示例中,步骤S15进一步包括:调试主程序轮询第一信号位,并
判断第一信号位是否为有效值,响应于第一信号位为有效值,确定获取到第一通知信息。如
果调试主程序没有获取到第一通知信息,则会一直基于轮询机制等待接收第一通知信息;
如果调试主程序获取到第一通知信息,则表示协处理器120中运行的调试过程代码已经执
行到调试指令并且跳转至调试辅助程序,因此调试主程序会进行后续操作。
[0088] 例如,在步骤S16中,若获取到第一通知信息,调试主程序访问存储空间以获取运行状态信息,并将第一信号位设置为无效值。例如,在调试辅助程序发送第一通知信息之前
(例如在调试辅助程序将第一信号位设置为有效值之前),调试辅助程序会将调试过程代码
当前的运行状态信息存储在存储空间中。因此在步骤S16中,在调试主程序获取到第一通知
信息后,调试主程序通过访问存储空间可以读取到运行状态信息,然后将第一信号位设置
为无效值。
[0089] 例如,在步骤S17中,根据运行状态信息,调试主程序会执行打印操作和/或接收指令操作,从而实现程序的调试。例如,如图5所示,步骤S17可以进一步包括如下操作。
[0090] 步骤S171:判断调试指令所在的调试位置表示的断点是否命中;
[0091] 步骤S172:响应于断点命中,接收用户输入的指令以作为待执行指令;
[0092] 步骤S173:响应于断点未命中,将继续执行指令设置为待执行指令;
[0093] 步骤S174:响应于待执行指令为打印指令,根据标准调试文件打印运行状态信息后继续接收用户输入的指令;
[0094] 步骤S175:响应于待执行指令不是打印指令,将待执行指令存入存储空间后向调试辅助程序发送第二通知信息。
[0095] 例如,在步骤S171中,首先要判断调试指令所在的调试位置表示的断点是否命中。例如,调试位置表示调试过程代码的断点,也即是,用户可能希望进行查看的代码位置。步
骤S171可以进一步包括:响应于断点处于启用状态且不是条件断点,确定断点命中;响应于
断点处于启用状态且是条件断点,并且条件断点对应的条件成就,确定断点命中。例如,当
某一断点不是条件断点时,则不需要判断对应的条件是否成就(条件是否满足),只需要该
断点处于启用状态(有效状态),则可以确定该断点命中,反之则未命中。如果某一断点是条
件断点,则不仅需要判断该断点是否处于启用状态,还需要判断对应的条件是否成就,当该
断点对应的条件成就(条件满足)并且该断点处于启用状态时,则确定该断点命中,反之则
未命中。
[0096] 例如,在步骤S172中,如果断点命中,则接收用户输入的指令以作为待执行指令。这时,用户可以通过输入设备(例如键盘、鼠标、触摸屏等)输入指令,用户输入的指令作为
待执行指令。
[0097] 例如,在步骤S173中,若断点未命中,则将继续执行指令设置为待执行指令。此时,不需要等待用户输入指令,而是直接将继续执行指令设置为待执行指令。例如,继续执行指
令可以为continue指令,continue指令是程序调试过程中常用的一类指令。
[0098] 例如,在步骤S174中,在得到待执行指令之后,若待执行指令为打印指令,则根据标准调试文件打印运行状态信息,之后继续接收用户输入的指令。例如,打印指令为print
指令,print指令是程序调试过程中常用的一类指令。例如,标准调试文件为DWARF信息文
件,是一种广泛应用的标准调试格式,其包含了源代码中变量、类型、函数等对象到硬件底
层存储的对应关系,DWARF信息文件由编译器产生且用于高级语言调试。具体地,DWARF信息
文件包含高级语言的代码行与可执行二进制文件中的指令行之间的映射关系,并且还可以
包含变量与寄存器之间的映射关系。
[0099] 根据标准调试文件,可以确定需要打印的信息,从而可以打印当前的运行状态信息,例如打印变量值等。这里,“打印”是指将信息以用户可以获取的方式输出,例如显示在
显示屏上、写入到指定的存储位置、传输到指定的接口程序、或者通过打印机打印等,可以
采用任意适用的方式输出信息,本公开的实施例对此不作限制。在打印运行状态信息之后,
又继续接收用户输入的指令。
[0100] 例如,在步骤S175中,如果待执行指令不是打印指令,则将待执行指令存入存储空间,之后向调试辅助程序发送第二通知信息。例如,第二通知信息表示调试主程序响应了第
一通知信息,也即,通过第二通知信息告知调试辅助程序在主处理器110中运行的调试主程
序已经读取了运行状态信息并且已将待执行指令存入了存储空间。
[0101] 例如,向调试辅助程序发送第二通知信息可以包括:调试主程序将存储在存储空间中的第二信号位设置为有效值。例如,在协处理器120中运行的调试辅助程序基于轮询机
制等待获取由调试主程序发送的第二通知信息,例如轮询第二信号位并判断第二信号位是
否为有效值。如果调试辅助程序没有获取到第二通知信息(第二信号位一直为无效值),则
会一直基于轮询机制等待接收第二通知信息;如果调试辅助程序获取到第二通知信息(第
二信号位为有效值),则会进行后续操作。
[0102] 返回至图3,在步骤S18中,若获取到第二通知信息(例如查询到第二信息位为有效值),则调试辅助程序访问存储空间以读取待执行指令,并将第二信号位设置为无效值。由
此,可以将待执行指令从主处理器110传递至协处理器120,从而实现待执行指令的传递。
[0103] 例如,在步骤S19中,在读取到待执行指令后,根据待执行指令的类型,确定是否从调试辅助程序跳转以使协处理器120恢复执行调试过程代码。例如,如图6所示,步骤S19可
以进一步包括如下操作。
[0104] 步骤S191:响应于待执行指令为继续执行指令或单步执行指令,从调试辅助程序跳转至调试过程代码,并向调试主程序发送第三通知信息;
[0105] 步骤S192:响应于待执行指令不是继续执行指令且不是单步执行指令,执行待执行指令后向调试主程序发送第三通知信息,并基于轮询机制获取由调试主程序发送的第二
通知信息。
[0106] 例如,在步骤S191中,若待执行指令为继续执行指令(continue指令)或单步执行指令,则从调试辅助程序跳转至调试过程代码,以继续运行调试过程代码,并向调试主程序
发送第三通知信息。例如,单步执行指令为next指令,next指令是程序调试过程中常用的一
类指令。第三通知信息表示调试辅助程序响应了待执行指令,也即,在该情形下,通过第三
通知信息告知调试主程序协处理器120已经跳转至调试过程代码。
[0107] 例如,可以在存储空间中存储第三信号位,第三信号位可以设置为有效值,也可以设置为无效值,从而实现状态的变更,以达到传递信息的目的。例如,在一些示例中,第三信
号位可以为1位二进制数,“1”为有效值,“0”为无效值。当然,本公开的实施例不限于此,可
以采用任意的数据类型和数据位数来表示第三信号位,这可以根据实际需求而定。例如,向
调试主程序发送第三通知信息可以包括:调试辅助程序将存储在存储空间中的第三信号位
设置为有效值。由此,可以实现第三通知信息的传递。
[0108] 需要说明的是,第一信号位、第二信号位、第三信号位的表示方式和数据类型可以相同,也可以不同,这可以根据实际需求而定,本公开的实施例对此不作限制。例如,可以在
存储空间中指定三个不同的存储位置(也即,指定三个不同的地址),以分别存储第一信号
位、第二信号位、第三信号位。调试主程序和调试辅助程序可以分别到指定的存储位置查询
第一信号位、第二信号位、第三信号位,从而分别实现第一通知信息、第二通知信息、第三通
知信息的传递。例如,本公开的实施例中,调试主程序和调试辅助程序通过轮询第一信号
位、第二信号位、第三信号位,从而建立实时交流协议。
[0109] 例如,在步骤S192中,若待执行指令不是继续执行指令且不是单步执行指令(既不是continue指令,也不是next指令),则执行该待执行指令,之后向调试主程序发送第三通
知信息,然后开始基于轮询机制获取由调试主程序发送的第二通知信息,也即,轮询第二信
号位。第三通知信息表示调试辅助程序响应了待执行指令,也即,在该情形下,通过第三通
知信息告知调试主程序协处理器120已经执行了该待执行指令。例如,待执行指令可以是除
了continue指令和next指令以外的其他任意类型的指令,协处理器120根据待执行指令的
类型执行该待执行指令即可。例如,在一些示例中,待执行指令可以是更改内存和寄存器值
的指令,该指令可以根据用户的设置更改内存和寄存器值,从而便于用户进行程序调试。
[0110] 返回至图3,在步骤S20中,调试主程序基于轮询机制查询获取由调试辅助程序发送的第三通知信息。例如,在一些示例中,步骤S20可以进一步包括:调试主程序轮询第三信
号位,并判断第三信号位是否为有效值,响应于第三信号位为有效值,确定获取到第三通知
信息。例如,当协处理器120跳转以执行调试过程代码,或者执行待执行指令后,协处理器
120中的调试辅助程序会将存储空间中的第三信号位设置为有效值,从而便于主处理器110
中的调试主程序查询,以达到传递第三通知信息的目的。
[0111] 例如,在步骤S21中,当获取到第三通知信息时,也即,查询到第三信号位为有效值时,根据待执行指令的类型,确定调试主程序的执行分支。例如,如图7所示,步骤S21可以进
一步包括如下操作。
[0112] 步骤S211:判断待执行指令是否为继续执行指令或单步执行指令;
[0113] 步骤S212:响应于待执行指令是继续执行指令或单步执行指令,基于轮询机制获取由调试辅助程序发送的第一通知信息;
[0114] 步骤S213:响应于待执行指令不是继续执行指令且不是单步执行指令,继续接收用户输入的指令。
[0115] 例如,在步骤S211中,判断待执行指令是否为继续执行指令(continue指令)或单步执行指令(next指令)。由于调试主程序在此前将待执行指令写入存储空间时留存有待执
行指令的备份,因此,调试主程序此时可以判断该待执行指令的类型。
[0116] 例如,在步骤S212中,若待执行指令是继续执行指令(continue指令)或单步执行指令(next指令),则调试主程序基于轮询机制获取由调试辅助程序发送的第一通知信息。
类似地,调试主程序可以轮询第一信号位是否为有效值。当第一信号位为有效值时,则确定
获取到第一通知信息;若第一信号位为无效值时,则继续轮询第一信号位。
[0117] 例如,在步骤S213中,若待执行指令不是继续执行指令(continue指令)且不是单步执行指令(next指令),则调试主程序继续接收用户输入的指令。
[0118] 在本公开的实施例中,通过执行上述步骤S11‑S21,可以使协处理器120(例如GPU)执行目标程序代码并且在断点处暂停下来,使用户能够检查和更改GPU的内存和寄存器值,
等待用户输入指令之后再恢复运行目标程序代码。通过调试主程序与调试辅助程序的配
合,可以提供打印、更改内存和寄存器值、继续执行、单步执行等多种功能。该方法可以实现
GPU的程序调试,无需使用硬件中断指令,对GPU的硬件条件要求低,不依赖硬件中断指令的
支持(例如不依赖Trap指令的支持),适用范围广。
[0119] 例如,在一些实施例中,为了在程序调试的过程中实现单步执行的功能,该方法还可以进一步包括插入调试指令的步骤。
[0120] 在第一种方式中,该方法可以进一步包括步骤S22,以插入调试指令从而实现单步执行的功能。
[0121] 步骤S22:响应于用户输入的指令为单步执行指令,基于标准调试文件,以目标程序代码中对应于目标程序下一行语句的代码处作为调试位置,插入调试指令,其中,调试位
置表示的断点默认为启用状态。
[0122] 例如,在步骤S22中,若指令内存是可读可写的,则当用户输入的指令为单步执行指令(next指令)时,主处理器110中运行的调试主程序根据标准调试文件确定出高级语言
中的下一行语句在目标程序代码中对应的代码位置,并且在GPU的指令内存中目标程序代
码中对应的代码处插入调试指令,该调试位置作为单步临时断点。并且,该调试位置表示的
断点默认设置为启用状态(有效状态)。由此,当协处理器120执行调试过程代码并且执行到
该调试位置时,会触发跳转,协处理器120会跳转以执行调试辅助程序,从而可以执行上述
步骤S11‑S21,由此实现单步执行的程序调试。
[0123] 例如,在第二种方式中,如图8所示,该方法可以进一步包括步骤S23‑S24,以插入调试指令从而实现单步执行的功能。
[0124] 步骤S23:以目标程序代码中对应于目标程序每一行语句的代码处作为调试位置,插入调试指令,并且根据预设状态表设置各个调试位置表示的断点是否为启用状态;
[0125] 步骤S24:响应于用户输入的指令为单步执行指令,基于标准调试文件,将目标程序代码中对应于目标程序下一行语句的代码处所对应的调试位置表示的断点更新为启用
状态。
[0126] 例如,在步骤S23中,若指令内存是只读的,在GPU内核执行过程中无法新增断点,因此为了实现单步执行功能,需要在加载之前在目标程序代码中对应于目标程序每一行语
句的代码处均插入调试指令。例如,预设状态表记录各个调试位置表示的断点的状态,需要
进行调试的调试位置表示的断点为启用状态(有效状态),其余的调试位置表示的断点则设
置为非启用状态(无效状态)。根据预设状态表设置各个调试位置表示的断点的状态,从而
标识该调试位置是否为用户需要调试的断点。例如,如果某一调试位置表示的断点设置为
启用状态(也即,对应的断点被启用),则在执行前述步骤S11‑S21时,根据前述的操作可以
实现程序调试;如果某一调试位置表示的断点设置为非启用状态(也即,对应的断点未启
用),则在执行前述步骤S11‑S21时,会在判断断点是否命中时认为该断点未命中,从而避免
错误地中断程序执行。
[0127] 例如,在步骤S24中,若用户输入的指令为单步执行指令,则基于标准调试文件,将目标程序代码中对应于目标程序下一行语句的代码处所对应的调试位置表示的断点更新
为启用状态。也即是,用户输入单步执行指令相当于将下一行语句对应的代码处的调试位
置表示的断点设为启用状态。由此,对应于下一行语句的代码处的调试位置表示的断点被
启用,则在执行前述步骤S11‑S21时,根据前述的操作可以实现单步执行。
[0128] 在本公开的实施例中,可以根据GPU的指令内存的不同,选择上述两种方式中合适的方式来实现单步执行。当然,本公开的实施例不限于此,也可以采用其他任意适用的方式
来实现单步执行,而不限于上述两种方式,这可以根据实际需求而定。
[0129] 图9为本公开一些实施例提供的一种用于调试由协处理器执行的目标程序代码的方法的工作流程图之一,图10为本公开一些实施例提供的一种用于调试由协处理器执行的
目标程序代码的方法的工作流程图之二。下面结合图9和图10对本公开实施例提供的方法
的工作流程进行示意性说明。需要注意的是,图9为协处理器(Device侧)的工作流程,图10
为系统侧(Host侧)的工作流程。在该示例中,协处理器为GPU,该GPU上设置有高带宽内存
(HBM),该HBM中存储有第一信号位FA、第二信号位FB、第三信号位FC,并且该HBM既可以从
GPU内部读写,也可以从系统侧进行读写。
[0130] 如图9所示,首先,系统侧加载目标程序代码,并在断点处插入调试指令,由此可以得到调试过程代码,并将调试过程代码上载至GPU。并且,调试辅助程序也被上载至GPU。图9
中的虚线框表示虚线框内的操作不在GPU上执行。
[0131] 接着,GPU开始程序执行。当执行到断点处的调试指令时,GPU跳转至调试辅助程序并开始执行调试辅助程序。调试辅助程序将GPU的寄存器值和栈内容存入GPU的HBM,然后将
第一信号位FA置位,也即设置为1。需要说明的是,在后文的说明中,“置位”表示设置为1,相
同说明不再赘述。然后调试辅助程序开始以轮询方式检查第二信号位FB是否置位。如果第
二信号位FB没有置位,则调试辅助程序一直轮询检查。
[0132] 然后,如图10所示,在系统侧,调试主程序将调试过程代码和调试辅助程序上载至GPU之后会开始以轮询方式检查第一信号位FA是否置位。如果第一信号位FA置位,则读取
HBM,将寄存器值和栈内容从HBM移到系统侧,之后将第一信号位FA清零。
[0133] 然后,判断是否断点命中。关于断点命中的判断方式可以参考上文中关于步骤S171的说明,此处不再赘述。若断点命中,则等待用户输入指令,例如通过输入设备接收用
户输入的指令,将用户输入的指令作为待执行指令。若断点未命中,则自动将待执行指令设
置为继续执行指令(continue指令)。
[0134] 接着判断待执行指令是否为打印指令(print指令)。如果是print指令,则根据DWARF信息打印变量值,然后接着等待用户输入下一个指令。如果不是print指令,则将用户
指令信息(也即待执行指令)写入HBM,之后将第二信号位FB置位。然后开始以轮询方式检查
第三信号位FC是否置位。
[0135] 如图9所示,此时GPU上运行的调试辅助程序检查到第二信号位FB置位,则将第二信号位FB清零,并且从HBM读取用户指令信息(待执行指令)。接着判断待执行指令是否为继
续执行指令(continue指令)或单步执行指令(next指令)。若是continue指令或next指令,
则调试辅助程序将第三信号位FC置位,并跳转至调试过程代码,使GPU程序恢复执行。若既
不是continue指令也不是next指令,则调试辅助程序根据指令的具体类型执行对应操作,
然后将第三信号位FC置位,并且开始继续检查第二信号位FB是否置位。
[0136] 如图10所示,此时系统侧的调试主程序检查到第三信号位FC置位,则判断待执行指令是否为继续执行指令(continue指令)或单步执行指令(next指令)。若是continue指令
或next指令,则开始继续检查第一信号位FA是否置位。若既不是continue指令也不是next
指令,则继续等待用户输入下一个指令。
[0137] 由此,结合图9和图10可知,通过系统侧的调试主程序和GPU上运行的调试辅助程序的互相配合,可以提供打印、更改内存和寄存器值、继续执行、单步执行等多种功能,从而
实现GPU的程序调试。该方法无需使用硬件中断指令,对GPU的硬件条件要求低,不依赖特定
硬件指令的支持,适用范围广。
[0138] 需要说明的是,图9和图10中示出的调试主程序与调试辅助程序的交互方式仅是示意性的,而非限制性的,可以根据实际需求调整调试主程序与调试辅助程序的交互方式,
本公开的实施例对此不作限制,只要能建立实时交流协议即可。
[0139] 图11为本公开一些实施例提供的一种用于调试由协处理器执行的目标程序代码的方法的流程示意图。如图11所示,在一些实施例中,该方法包括如下操作。
[0140] 步骤S31:获取调试过程代码,其中,调试过程代码包括目标程序代码以及插入到目标程序代码中至少一个调试位置的至少一个调试指令;
[0141] 步骤S32:将调试过程代码以及调试辅助程序上载至协处理器,从而使协处理器执行调试过程代码;
[0142] 步骤S33:获取调试辅助程序返回的调试过程代码当前的运行状态信息,其中,协处理器运行调试过程代码的过程中,响应于执行至少一个调试指令,从调试过程代码跳转
以执行调试辅助程序。
[0143] 例如,上述步骤S31‑S33可以用于系统侧,例如由系统侧运行的调试主程序执行。关于该方法的详细说明可参考上文关于图2至图10所示的方法的描述,此处不再赘述。
[0144] 图12为本公开一些实施例提供的另一种用于调试由协处理器执行的目标程序代码的方法的流程示意图。如图12所示,在一些实施例中,该方法包括如下操作。
[0145] 步骤S41:接收调试过程代码,其中,调试过程代码包括目标程序代码以及插入到目标程序代码中至少一个调试位置的至少一个调试指令;
[0146] 步骤S42:接收调试辅助程序;
[0147] 步骤S43:运行调试过程代码,响应于执行至少一个调试指令,从调试过程代码跳转以执行调试辅助程序,并由调试辅助程序返回调试过程代码当前的运行状态信息。
[0148] 例如,上述步骤S41‑S43可以用于协处理器,例如GPU等。关于该方法的详细说明可参考上文关于图2至图10所示的方法的描述,此处不再赘述。
[0149] 需要说明的是,本公开实施例提供的用于调试由协处理器执行的目标程序代码的方法不限于上文描述的步骤和顺序,还可以包括更多或更少的步骤,各个步骤的执行顺序
可以根据实际需求而定,本公开的实施例对此不作限制。
[0150] 本公开至少一个实施例还提供一种用于调试由协处理器执行的目标程序代码的装置。该装置可以实现图形处理器的程序调试,无需使用硬件中断指令,对图形处理器的硬
件条件要求低,不依赖特定硬件指令的支持,适用范围广。
[0151] 图13为本公开一些实施例提供的一种用于调试由协处理器执行的目标程序代码的装置的示意框图。如图13所示,该装置50包括代码获取单元51、上载单元52、调试辅助单
元53。
[0152] 代码获取单元51配置为获取调试过程代码。例如,调试过程代码包括目标程序代码以及插入到目标程序代码中至少一个调试位置的至少一个调试指令。代码获取单元51可
以为图1中示出的代码获取单元111,并且可以执行图2所示的方法中的步骤S11。
[0153] 上载单元52配置为将调试过程代码以及调试辅助程序上载至协处理器。上载单元52可以为图1中示出的上载单元112,并且可以执行图2所示的方法中的步骤S12。
[0154] 调试辅助单元53配置为在协处理器执行调试过程代码的过程中,响应于执行至少一个调试指令,从调试过程代码跳转,并返回调试过程代码当前的运行状态信息。调试辅助
单元53可以为图1中示出的调试辅助单元121,并且可以执行图2所示的方法中的步骤S13。
[0155] 例如,代码获取单元51、上载单元52、调试辅助单元53可以为硬件、软件、固件以及它们的任意可行的组合。例如,代码获取单元51、上载单元52、调试辅助单元53可以为专用
或通用的电路、芯片或装置等,也可以为处理器和存储器的结合。关于代码获取单元51、上
载单元52、调试辅助单元53的具体实现形式,本公开的实施例对此不作限制。
[0156] 需要说明的是,本公开的实施例中,装置50的各个单元与前述的方法的各个步骤对应,关于该装置50的具体功能可以参考上文中关于方法的相关描述,此处不再赘述。图13
所示的装置50的组件和结构只是示例性的,而非限制性的,根据需要,该装置50还可以包括
其他组件和结构。
[0157] 本公开至少一个实施例还提供一种电子设备。该电子设备可以实现图形处理器的程序调试,无需使用硬件中断指令,对图形处理器的硬件条件要求低,不依赖特定硬件指令
的支持,适用范围广。
[0158] 图14为本公开一些实施例提供的一种电子设备的示意框图。如图14所示,电子设备60包括用于调试由协处理器执行的目标程序代码的装置61。例如,装置61可以为图13所
示的用于调试由协处理器执行的目标程序代码的装置50。例如,该电子设备60可以为具有
中央处理器和图形处理器的计算机、服务器等,或者为其他任意的具有计算功能的电子设
备,本公开的实施例对此不作限制。关于该电子设备60的相关说明可参考上文中关于装置
50的描述,此处不再赘述。
[0159] 有以下几点需要说明:
[0160] (1)本公开实施例附图只涉及到本公开实施例涉及到的结构,其他结构可参考通常设计。
[0161] (2)在不冲突的情况下,本公开的实施例及实施例中的特征可以相互组合以得到新的实施例。
[0162] 以上所述,仅为本公开的具体实施方式,但本公开的保护范围并不局限于此,本公开的保护范围应以所述权利要求的保护范围为准。