GDB中'Arglist'地址为何与函数参数地址不一致?
GDB中'Arglist'地址为何与函数参数地址不一致?
嗨,这个问题我之前调试的时候也碰到过,一开始摸不着头脑,搞懂GDB里Arglist的真实含义后就通透了,给你拆解下核心原因:
首先得明确,info frame里显示的Arglist,是函数所有参数在栈上的存储区域的起始基地址,不是单个参数的直接地址!它标记的是整个参数块的起点,而每个具体参数的地址,是这个基地址加上对应偏移量后的结果,自然和Arglist本身的地址不一样。
具体来说,有几个常见的触发场景:
- 参数在栈上的偏移存储:不管用哪种调用约定,参数都是按顺序排列在Arglist基地址之后的。比如32位系统用cdecl约定时,参数从右往左压栈,第一个参数会在Arglist加上(参数个数-1)*参数大小的位置;哪怕只有一个参数,也可能因为栈对齐要求,导致参数地址和Arglist存在偏移。
- 调用约定的寄存器传参影响:如果你的程序用了寄存器传参的调用约定(比如x86-64的System V,前6个参数用寄存器传递),函数参数一开始可能根本不在栈上——GDB显示的参数地址,其实是函数执行过程中把寄存器里的参数备份到栈上的位置,这个备份位置和Arglist标记的参数区域起点自然有偏移。
- 栈对齐的填充字节:现在很多架构要求栈帧按8字节或16字节对齐,哪怕你的参数只有4字节大小,编译器也会在栈上填充额外的空字节来满足对齐要求,这就会让参数地址和Arglist基地址之间出现空隙。
你可以动手验证下:用x/4xw 你的Arglist地址查看这个基地址开始的内存,会发现tcb_handle参数的值就藏在这些内存单元里,只是不在第一个位置而已。另外也可以用info args命令,直接看每个参数的地址和值,对比Arglist就能更清楚它们的偏移关系。
备注:内容来源于stack exchange,提问作者Sathyanarayan B
相关产品推荐
相关产品推荐

