在 GDB 中我可以执行以下操作并获取字符串文字的地址:
(gdb) p &"aaa"
$3 = (char (*)[4]) 0x614c20
据我了解,字符串文字是一个没有绑定符号的右值,但为什么我可以获取它的地址?
这是什么样的地址?它是存储所有字符串文字的地方吗?但是字符串文字是无限的,这是否意味着字符串文字是按需“创建并放入内存”的?
在 GDB 中我可以执行以下操作并获取字符串文字的地址:
(gdb) p &"aaa"
$3 = (char (*)[4]) 0x614c20
据我了解,字符串文字是一个没有绑定符号的右值,但为什么我可以获取它的地址?
这是什么样的地址?它是存储所有字符串文字的地方吗?但是字符串文字是无限的,这是否意味着字符串文字是按需“创建并放入内存”的?
GDB
malloc
在调试器内部调用来为字符串文字分配空间,然后将字符串文字写入新分配的内存块并返回其地址。它通过构建一个伪堆栈框架来实现这一点,该框架调用 malloc() 并设置为返回断点指令。然后它会默默地恢复程序,让对 malloc 的调用完成,然后在程序返回断点时重新控制程序。
malloc
你可以通过在其自身上设置断点,然后运行来证明这种情况确实发生了print &"foo"
。GDB 将命中断点并显示以下消息:如果您很好奇,可以检查第一个参数 ($rdi on x86-64) 的值并验证它是否等于 4(字符串文字的长度 + 1)。您还可以检查堆栈跟踪以查看伪断点返回地址。
这种行为可能令人惊讶;毕竟,人们通常不希望
print &"foo"
在调试对象中执行代码。如果要禁用此行为,请运行set may-call-functions off
。运行此操作后,类似这样的表达式print &"foo"
将产生Cannot call functions in the program: may-call-functions is off.
。print
不需要执行调试对象函数的语句将继续正常工作。