No GDB, posso fazer o seguinte e obter o endereço de uma string literal:
(gdb) p &"aaa"
$3 = (char (*)[4]) 0x614c20
Pelo que entendi, uma string literal é um rvalue sem nenhum símbolo ao qual se vincula, mas por que posso obter seu endereço?
Que tipo de endereço é esse? É algum lugar onde todos os literais de string são armazenados? Mas há literais de string infinitos, isso significa que o literal de string é "criado e colocado na memória" sob demanda?
O GDB faz chamadas
malloc
dentro do depurador para alocar espaço para o literal de string, depois grava o literal de string no pedaço de memória recém-alocado e retorna o endereço dele.Ele consegue isso construindo um stack frame falso que chama malloc() e que é configurado para retornar a uma instrução de ponto de interrupção. Ele então silenciosamente retoma o programa, deixando a chamada para malloc ser concluída, e então retoma o controle do programa quando o programa retorna ao ponto de interrupção.
Você pode provar que isso está acontecendo definindo um ponto de interrupção em
malloc
si mesmo e, em seguida, executandoprint &"foo"
. O GDB atingirá o ponto de interrupção com a seguinte mensagem:Se estiver curioso, você pode verificar o valor do primeiro argumento ($rdi em x86-64) e verificar se ele é igual a 4 (comprimento do literal da string + 1). Você também pode verificar o rastreamento de pilha para ver o endereço de retorno do ponto de interrupção falso.
Esse comportamento pode ser surpreendente; afinal, normalmente não se espera
print &"foo"
executar código no debuggee. Se você quiser desabilitar esse comportamento, executeset may-call-functions off
. Após executar isso, uma expressão comoprint &"foo"
produziráCannot call functions in the program: may-call-functions is off.
.print
instruções que não exigem a execução de funções debuggee continuarão a funcionar normalmente.