本次问题从一个bug入手,源文件非常简单,只包含一个函数:
int call2b(char c, float f1, short 2, double d1, int i, float f2, long l, double d2)
{
c='a';f1=0.0;s=5;d1=0.0;
i=6;
f2 = 0.1;l=7;d2=0.2
return i;
}
该函数使用gcc编译(参数‘-g -O0’)之后会产生dwarf调试信息,其中每个formal parm都会有一个die。每个die描述的信息有:name、file、line、type以及location。但是问题来了:
(1)前面四个parm的调试信息都是完整的,但是从第五个参数int i开始,后面的parm的调试信息中都没有location信息。
(2)把i=6该语句注释掉,再重新编译,此时所有的parm的调试信息都是完整的。
这么两个问题让我百思不得其解,但是calm down。仔细分析一下,就会发现,调试信息是从int i开始不正常的,而使用的gcc的体系结构后端的abi中规定,传参的寄存器有5个,当传参寄存器用完之后那么就使用堆栈传参。那么我们可以知道,前面四个参数刚好把5个传参寄存器用完了(double d1使用两个)。也就是说堆栈传参导致的问题。
那么接下来进行debug。
首先需要找到dwarf调试信息是在哪个pass中生成的。我们找到一个名为“final”的pass,该pass负责将rtl转化为assembly,并且输出dwarf调试信息。具体流程如图所示。
可见,前面部分负责输出assembly insns,而dwarf