GDB calls malloc
inside the debuggee to allocate space for the string literal, then writes the string literal to the freshly allocated memory chunk and returns the address of it.
It achieves this by building a fake stack frame which calls into malloc() and which is set up to return to a breakpoint instruction. It then silently resumes the program, letting the call to malloc complete, and then retakes control of the program when the program returns to the breakpoint.
You can prove that this is happening by setting a breakpoint on malloc
itself, then running print &"foo"
. GDB will hit the breakpoint with the following message:
The program being debugged stopped while in a function called from GDB.
Evaluation of the expression containing the function
(malloc) will be abandoned.
When the function is done executing, GDB will silently stop.
If you’re curious, you can check the value of the first argument ($rdi on x86-64) and verify that it’s equal to 4 (length of the string literal + 1). You can also check the stack trace to see the fake breakpoint return address.
This behaviour might be surprising; after all, one doesn’t normally expect print &"foo"
to execute code in the debuggee. If you want to disable this behaviour, run set may-call-functions off
. After running this, an expression like print &"foo"
will yield Cannot call functions in the program: may-call-functions is off.
. print
statements that don’t require executing debuggee functions will continue to work normally.
"aaa"
. So does gdb in that case fail to evaluate the expression or what does the address mean in that case? – Rhesusp &"aaa"
in gdb produces a result even in a program that doesn't contain any"aaa"
literal and it seems that each time it is evaluated it produces a different address. – Rhesusmalloc
etc and Storage of String Literals in memory c++ – Tayyebebprint &"blah blah this string is definitely not in the program blah blah"
. The resulting address will contain that string, as you can check withx/s
. The real answer is that GDB is creating the string literals by writing to the debuggee’s memory directly. – Leastways