在GDB中使用set命令修改变量时如何正确转换类型?
问题:GDB通过变量名修改GNU汇编程序变量失败
调试GNU汇编(GAS)程序时,尝试用变量名通过GDB的set命令修改变量值遇到以下问题:
- 执行
set constant = 666,GDB提示:'constant' has unknown type; cast it to its declared type - 添加类型转换后执行
set (int) constant = 666,报错:Left operand of assignment is not an lvalue - 仅能通过变量地址
set *0x804a000 = 666完成修改,希望直接用变量名操作。
GDB交互记录
(peter)-[~/ri/rfe/p88] $ gdb -q moving_data_between_registers_and_memory Reading symbols from moving_data_between_registers_and_memory... (No debugging symbols found in moving_data_between_registers_and_memory) (gdb) br _start Breakpoint 1 at 0x8049000 (gdb) r Starting program: /home/peter/Documents/.../moving_data_between_registers_and_memory zshenv Breakpoint 1, 0x08049000 in _start () (gdb) print constant 'constant' has unknown type; cast it to its declared type (gdb) print (int) constant $1 = 10 (gdb) si 0x08049001 in mov_immediate_data_between_registers_and_memory () (gdb) si 0x08049006 in mov_immediate_data_between_registers_and_memory () (gdb) si 0x0804900b in exit () (gdb) print (int) constant $2 = 777 (gdb) set constant = 666 'constant' has unknown type; cast it to its declared type (gdb) set (int) constant = 666 Left operand of assignment is not an lvalue. (gdb) print &constant $3 = (<data variable, no debug info> *) 0x804a000 (gdb) set *0x804a000 = 666 (gdb) print (int) constant $4 = 666 (gdb)
汇编源码
#moving_data_between_registers_and_memory: mov data between regs and mem .section .data #.section .bss constant: .int 10 # .int 0 .section .text .globl _start _start: nop #used for debugging purposes mov_immediate_data_between_registers_and_memory: movl $777, %eax #mov immediate value 777 to eax movl %eax, constant #mov eax value into constant mem value exit: movl $1, %eax #sys_exit system call movl $0, %ebx #exit code 0 successful execution int $0x80
解决方案
方案1:编译时生成调试符号
问题根源是编译时未生成调试信息,GDB无法识别变量的类型和存储属性。编译时添加-g参数生成调试符号:
as -g moving_data_between_registers_and_memory.s -o moving_data_between_registers_and_memory.o ld moving_data_between_registers_and_memory.o -o moving_data_between_registers_and_memory
重新编译后,GDB能直接识别constant的类型,执行set constant = 666即可正常修改变量值。
方案2:GDB内手动指定变量类型(无需重新编译)
如果不想重新编译,可通过指针操作实现变量名修改:
- 直接通过地址转换赋值:
set variable *(int *)&constant = 666
- 先定义指针变量再赋值:
set $constant_ptr = (int *)&constant set *$constant_ptr = 666
解释:(int)constant是将变量值转换为int类型(右值,无法赋值),而*(int *)&constant是先取变量地址、转换为int指针,再解引用得到可赋值的左值。
内容的提问来源于stack exchange,提问作者nostromo
相关产品推荐
相关产品推荐

