gdb 调试 symbol

 

0

I'm following linux bootloading using u-boot (using SPL falcon mode where u-boot-spl launches linux directly) on a qemu virtual machine. Now the code jumped to linux kernel and because I have done add-symbol-file vmlinux 0x80081000 I can follow the kernel code step by step using gdb connected to the virtual machine. Actually I loaded the kernel image to 0x80080000 but I had to set the address to 0x80081000 to make the source code appear on the gdb correctly according to the PC value(I don't know why this difference of 0x1000 is needed).
Later I found the kernel sets up the page table (identity mapping and swap table) and jumps to __primary_switched and this is where pure kernel virtual address is used first time for the PC. This is where the call is made at the end of the head.S file.

ldr x8, =__primary_switched
adrp    x0, __PHYS_OFFSET
br  x8

In the symbol file (vmlinux, an elf file), the symbols before __primary_switched are all mapped at virtual addresses (starting with 0xffffffc0..... high addresses) but the gdb could follow the source even when the PC value was using physical address. (The PC was initially loaded with physical address of the kernel start and PC relative jumps were being used until it jumps to __primary_switched, mmu disabled or using identity mapping) So does this mean, in doing add-symbol-file only the offset of the symbols from the start of text matters?
Another quetion : I can follow the kernel source with gdb but after __primary_switched, I cannot see the source. The debugger doesn't show the correct source location according to the now kernel virtual PC value. Should I tell the debugger to use correct offset using add-symbol-file again? if so how?

ADD (8:32 AM Wednesday, January 12, 2022, UTC)
I found from gdb manual,

"add-symbol-file filename [ -readnow | -readnever ] [ -o offset ] [ textaddress ] [ -s section address ... ] The add-symbol-file command reads additional symbol table information from the file filename. You would use this command when filename has been dynamically loaded (by some other means) into the program that is running. The textaddress parameter gives the memory address at which the file's text section has been loaded. You can additionally specify the base address of other sections using an arbitrary number of '-s section address' pairs. If a section is omitted, gdb will use its default addresses as found in filename. Any address or textaddress can be given as an expression. ..."

I changed my program a little bit to fix a problem. The readelf shows the .text section starting at ffffffc010080800. So I adjusted the command to "add-symbol-file vmlinux 0x80000800" and gdb shows the kernel source correct after jump to linux. Still it doesn't show me the source code after __primary_switched.

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .head.text        PROGBITS         ffffffc010080000  00010000
       0000000000000040  0000000000000000  AX       0     0     4
  [ 2] .text             PROGBITS         ffffffc010080800  00010800
       0000000000304370  0000000000000000  AX       0     0     2048
  [ 3] .rodata           PROGBITS         ffffffc010390000  00320000
   .... (skip) ...
  [12] .notes            NOTE             ffffffc01045be18  003ebe18
       000000000000003c  0000000000000000   A       0     0     4
  [13] .init.text        PROGBITS         ffffffc010470000  003f0000
       0000000000027ec8  0000000000000000  AX       0     0     4
  [14] .exit.text        PROGBITS         ffffffc010497ec8  00417ec8
       000000000000046c  0000000000000000  AX       0     0     4

Since '__primary_switched' resides in section .init.text, I tried adding "-s .init.text 0xffffffc010470000" or "-s .init_text 0x803ef800"(physcial address) to the add-symbol-file command to no avail. Is my command wrong? Or could this be from page table (virtual -> Physical) problem because I see synchronous exception right after I enter __primary_switched (I see PC value has become 0x200. If the exception vector is located in 0x0, this is the vector entry for synch exception like undefined instruction. I should also check the vector base address has not been set correctly.)

0
 

I found my kernel load address was wrong (__PHYS_OFFSET was below physical ddr address start). After fixing it, the PC increments normally with kernel virtual address and I should just apply the add-symbol-file command using the virtual address.
This was the new section addresses.

        Section Headers:
          [Nr] Name              Type             Address           Offset
               Size              EntSize          Flags  Link  Info  Align
          [ 0]                   NULL             0000000000000000  00000000
               0000000000000000  0000000000000000           0     0     0
          [ 1] .head.text        PROGBITS         ffffffc010080000  00010000
               0000000000000040  0000000000000000  AX       0     0     4
          [ 2] .text             PROGBITS         ffffffc010080800  00010800
               0000000000304370  0000000000000000  AX       0     0     2048
          [ 3] .rodata           PROGBITS         ffffffc010390000  00320000
               00000000000a6385  0000000000000000  WA       0     0     4096
          [ 4] .modinfo          PROGBITS         ffffffc010436385  003c6385
               00000000000018ff  0000000000000000   A       0     0     1
          [ 5] .pci_fixup        PROGBITS         ffffffc010437c90  003c7c90
               00000000000020f0  0000000000000000   A       0     0     16
          [ 6] __ksymtab         PROGBITS         ffffffc010439d80  003c9d80
               0000000000006d20  0000000000000000   A       0     0     4
          [ 7] __ksymtab_gpl     PROGBITS         ffffffc010440aa0  003d0aa0
               0000000000005808  0000000000000000   A       0     0     4
          [ 8] __ksymtab_strings PROGBITS         ffffffc0104462a8  003d62a8
               00000000000134f2  0000000000000000   A       0     0     1
          [ 9] __param           PROGBITS         ffffffc0104597a0  003e97a0
               0000000000000b68  0000000000000000   A       0     0     8
          [10] __modver          PROGBITS         ffffffc01045a308  003ea308
               0000000000000cf8  0000000000000000   A       0     0     8
          [11] __ex_table        PROGBITS         ffffffc01045b000  003eb000
               0000000000000e18  0000000000000000   A       0     0     8
          [12] .notes            NOTE             ffffffc01045be18  003ebe18
               000000000000003c  0000000000000000   A       0     0     4
          [13] .init.text        PROGBITS         ffffffc010470000  003f0000
               0000000000027ec8  0000000000000000  AX       0     0     4
  [14] .exit.text        PROGBITS         ffffffc010497ec8  00417ec8

The final kernel image is loaded at 0x80080000. Then __PHYS_OFFSET becomes 0x80000000. (TEXT_OFFSET is 0x80000 by default). Now I can debug the kernel source before __primary_switch using this command.

add-symbol-file images/vmlinux 0x80080800 -s .head.text 0x80080000 -s .init.text 0x803f7800

And after the kernel entered __primary_switched (now kernel virtual address is used), I added this command to see the source and I can follow code using qemu and gdb step-by-step.

add-symbol-file images/vmlinux 0xffffffc010080800 -s .head.text 0xffffffc010080000 -s .init.text 0xffffffc010470000 Hope this helps someone later.

But after some days, I think I could just use add-symbol-file images/vmlinux 0xffffffc010080800 (applying all the section info).

 

 

https://wiki.stmicroelectronics.cn/stm32mpu/wiki/U-Boot_-_How_to_debug 

 

linux 使用 gdb

gdb 对于看系统内部是非常有用. 在这个级别精通调试器的使用要求对 gdb 命令有信心, 需要理解目标平台的汇编代码, 以及对应源码和优化的汇编码的能力.

 

调试器必须把内核作为一个应用程序来调用. 除了指定内核映象的文件名之外, 你需要在 命令行提供一个核心文件的名子. 对于一个运行的内核, 核心文件是内核核心映象,

/proc/kcore. 一个典型的 gdb 调用看来如下:

 

gdb /usr/src/linux/vmlinux /proc/kcore

 

第一个参数是非压缩的 ELF 内核可执行文件的名子, 不是 zImage 或者 bzImage 或者给 启动环境特别编译的任何东东.

 

gdb 命令行的第二个参数是核心文件的名子. 如同任何 /proc 中的文件, /proc/kcore 是在被读的时候产生的. 当 read 系统调用在 /proc 文件系统中执行时, 它映射到一个 数据产生函数,而不是一个数据获取函数; 我们已经在本章"使用 /proc 文件系统"一节中 利用了这个特点. kcore 用来代表内核"可执行文件", 以一个核心文件的形式; 它是一个 巨大的文件, 因为他代表整个的内核地址空间, 对应于所有的物理内存. 从 gdb 中, 你 可查看内核变量,通过发出标准 gdb 命令. 例如, p jiffies 打印时钟的从启动到当前时 间的嘀哒数.

 

当你从 gdb 打印数据, 内核仍然在运行, 各种数据项在不同时间有不同的值; 然而, gdb 通过缓存已经读取的数据来优化对核心文件的存取. 如果你试图再次查看 jiffies 变量, 你会得到和以前相同的答案. 缓存值来避免额外的磁盘存取对传统核心文件是正确的做法, 但是在使用一个"动态"核心映象时就不方便. 解决方法是任何时候你需要刷新 gdb 缓存 时发出命令 core-file /proc/kcore; 调试器准备好使用新的核心文件并且丢弃任何旧信 息. 然而, 你不会一直需要发出 core-file 在读取一个新数据时; gdb 读取核心以多个 几 KB 的块的方式, 并且只缓存它已经引用的块.

 

gdb 通常提供的不少功能在你使用内核时不可用. 例如, gdb 不能修改内核数据; 它希望 在操作内存前在它自己的控制下运行一个被调试的程序. 也不可能设置断点或观察点, 或 者单步过内核函数.

 

注意, 为了给 gdb 符号信息, 你必须设置 CONFIG_DEBUG_INFO 来编译你的内核. 结果是 一个很大的内核映象在磁盘上, 但是, 没有这个信息, 深入内核变量几乎不可能.

 

有了调试信息, 你可以知道很多内核内部的事情. gdb 愉快地打印出结构, 跟随指针, 等 等. 而有一个事情比较难, 然而, 是检查 modules. 因为模块不是传递给 gdb 的 vmlinux 映象, 调试器对它们一无所知. 幸运的是, 作为 2.6.7 内核, 有可能教给 gdb 需要如何 检查可加载模块.

 

Linux 可加载模块是 ELF 格式的可执行映象; 这样, 它们被分成几个节. 一个典型的模 块可能包含一打或更多节, 但是有 3 个典型的与一次调试会话相关:

 

.text

 

这个节包含有模块的可执行代码. 调试器必须知道在哪里以便能够给出回溯或者设 置断点.( 这些操作都不相关, 当运行一个调试器在 /proc/kcore 上, 但是它们在 使用 kgdb 时可能有用, 下面描述).

 

.bss

 

.data

 

这 2 个节持有模块的变量. 在编译时不初始化的任何变量在 .bss 中, 而那些要 初始化的在 .data 里.

 

使 gdb 能够处理可加载模块需要通知调试器一个给定模块的节加载在哪里. 这个信息在 sysfs 中, 在 /sys/module 下. 例如, 在加载 scull 模块后, 目录

/sys/module/scull/sections 包含名子为 .text 的文件; 每个文件的内容是那个节的基 地址.

 

我们现在该发出一个 gdb 命令来告诉它关于我们的模块. 我们需要的命令是 add- symble-flile; 这个命令使用模块目标文件名, .text 基地址作为参数, 以及一系列描述 任何其他感兴趣的节安放在哪里的参数. 在深入位于 sysfs 的模块节数据后, 我们可以 构建这样一个命令:

 

(gdb) add-symbol-file .../scull.ko 0xd0832000 \

-s .bss 0xd0837100 \

-s .data 0xd0836be0

 

我们已经包含了一个小脚本在例子代码里( gdbline ), 它为给定的模块可以创建这个命 令.

 

我们现在使用 gdb 检查我们的可加载模块中的变量. 这是一个取自 scull 调试会话的快 速例子:

 

(gdb) add-symbol-file scull.ko 0xd0832000 \

-s .bss 0xd0837100 \

-s .data 0xd0836be0

add symbol table from file "scull.ko" at

.text_addr = 0xd0832000

.bss_addr = 0xd0837100

.data_addr = 0xd0836be0 (y or n) y

Reading symbols from scull.ko...done.

(gdb) p scull_devices[0]

$1 = {data = 0xcfd66c50, quantum = 4000,

qset = 1000,

size = 20881,

access_key = 0,

...}

 

这里我们看到第一个 scull 设备当前持有 20881 字节. 如果我们想, 我们可以跟随数据 链, 或者查看其他任何感兴趣的模块中的东东.

 

这是另一个值得知道的有用技巧:

 

(gdb) print *(address)

 

这里, 填充 address 指向的一个 16 进制地址; 输出是对应那个地址的代码的文件和行 号. 这个技术可能有用, 例如, 来找出一个函数指针真正指向哪里.

 

我们仍然不能进行典型的调试任务, 如设置断点或者修改数据; 为进行这些操作, 我们需 要使用象 kdb( 下面描述 ) 或者 kgdb ( 我们马上就到 )这样的工具.

https://blog.csdn.net/hushui/article/details/122702411

https://m2m-tele.com/wiki/

U-boot debugging. part 2.

In previous chapter we got U-boot debuggable. Partially debuggable as we turned out. The thing we missed is relocation. The workaround provided in that document is simple enough but not might be comfortable. Here suggested workaround adopted to NetSoM to get fully functional u-boot debugging procedure.

Command line mode debugging

  • Start GDB server:
$ JLinkGDBServer -device MCIMX6Y2 -if JTAG -speed 1000
  • Start GDB session:
$ gdb-multiarch u-boot –nx

that command has to be called from U-boot folder (build_dir/target-arm_cortex-a7+neon-vfpv4_musl_eabi/u-boot-wirelessroad_ecspi3/u-boot-2017.07 in our case) with u-boot image compiled with debugging symbols

  • Connect to target device and load image:
(gdb) target remote localhost:2331
(gdb) monitor reset
(gdb) monitor halt
(gdb) monitor sleep 200
(gdb) load

check that program counter set correctly:

(gdb) display /x $pc
1: /x $pc = 0x87800000

here 0x87800000 is starting address u-boot image is placed.

  • Restore device tree binary blob:
(gdb) restore u-boot.dtb binary 0x87882d68
Restoring binary file u-boot.dtb into memory (0x87882d68 to 0x8788953b)

That address here is the end address of image.  It need to be done as in production mode (without debugger) U-boot checks for device tree binary blob at the address placed right after image:

$ ls -la u-boot.dtb u-boot-dtb.bin u-boot-nodtb.bin
-rw-rw-r– 1 al al 26579 окт 22 17:19 u-boot.dtb
-rw-rw-r– 1 al al 562491 окт 24 14:26 u-boot-dtb.bin
-rwxrwxr-x 1 al al 535912 окт 24 14:26 u-boot-nodtb.bin

here you see size of u-boot-nodtb.bin (u-boot image without dtb appended to the end) = 535912 = 0x82D68.
So if you will add it to the starting address of u-boot being placed: 0x82D68 + 0x87800000 = 0x87882D688 you will get it. Binary blob of dts – u-boot.dtb has size 26579. Being appended to u-boot-nodtb.bin (size 535912) gives you u-boot-dtb.bin (size 562491).
Another way to get this address – you can check for value of __end address in u-boot.map file:

$ cat u-boot.map | grep __end
*(.__end)
.__end 0x0000000087882d68 0x0 arch/arm/lib/built-in.o
  • Set breakpoint at relocate_code to prevent jumping to unprepared memory area and start execution:

(gdb) b relocate_code
Breakpoint 1 at 0x87802db4: file arch/arm/lib/relocate.S, line 81.
(gdb) c
Continuing.
Breakpoint 1, relocate_code () at arch/arm/lib/relocate.S:81
81 stmdb sp!, {lr}
1: /x $pc = 0x87802db4

at this moment program counter passed for board_init_f initialization procedure so we can place symbol file at target memory area program counter going to jump:

(gdb) add-symbol-file u-boot 0x8FF2B000
add symbol table from file “u-boot” at
.text_addr = 0x8ff2b000
(y or n) y
Reading symbols from u-boot…

without it you can continue executeion. Nothing brakes but you will not be able to set breakpoints as they will be placed in memory area starting from 0x87800000 u-boot image place initially while actual execution will be at relocated area starting from 0x8FF2B000. So by adding debugging symbols by new address you will get duplicated addresses for each debugging symbol:

(gdb) b board_init_r
Breakpoint 2 at 0x87815b4c: board_init_r. (2 locations)

and now is time for controlled jump:

(gdb) display /x $pc
2: /x $pc = 0x87802db4
(gdb) fin
Run till exit from #0 relocate_code () at arch/arm/lib/relocate.S:81
_main () at arch/arm/lib/crt0.S:116
116 bl relocate_vectors
1: /x $pc = 0x8ff2d8cc
2: /x $pc = 0x8ff2d8cc
(gdb) display /x $pc
3: /x $pc = 0x8ff2d8cc

here we check for program counter before relocate_code function being executed – 0x87802db4 and after – 0x8ff2d8cc. As you see we jumped to new memory area. Continue execution:

(gdb) c
Continuing.

Breakpoint 2, board_init_r (new_gd=0x8ef28eb8, dest_addr=2415046656) at common/board_r.c:904
904 {
1: /x $pc = 0x8ff40b4c
2: /x $pc = 0x8ff40b4c
3: /x $pc = 0x8ff40b4c

Still able to catch PC by breakpoints.
How to determine relocation address? Explained in same document mentioned above. You can check it by typing bdinfo command in u-boot console:

=> bdinfo
arch_number = 0x00000000
boot_params = 0x80000100
DRAM bank = 0x00000000
-> start = 0x80000000
-> size = 0x10000000
eth0name = FEC
ethaddr = 86:72:04:c5:7e:83
current eth = FEC
ip_addr = 192.168.31.99
baudrate = 115200 bps
TLB addr = 0x8FFF0000
relocaddr = 0x8FF2B000
reloc off = 0x0872B000
irq_sp = 0x8EF216C0
sp start = 0x8EF216B0
Early malloc usage: 188 / 400
fdt_blob = 8ef216d8

here relocaddr is memory address u-boot going to relocate itself and fdt_blob – address device tree binary blob to be found. Another way to get relocation address is interrupt execution of u-boot under debugger and type following:

Continuing.
^C
Program received signal SIGTRAP, Trace/breakpoint trap.
0x8ff62d00 in mxc_serial_getc () at drivers/serial/serial_mxc.c:161
161 while (__REG(UART_PHYS + UTS) & UTS_RXEMPTY)
1: /x $pc = 0x8ff62d00
2: /x $pc = 0x8ff62d00
3: /x $pc = 0x8ff62d00
(gdb) p /x gd->relocaddr
$1 = 0x8ff2b000

 

Doing same in Eclipse.

in eclipse we have to provide same commands to load dtb blob, to set breakpoint:

u-boot debugging

Then we have to start execution:

it should stop at relocate_code function. Same commands we entered to load debugging symbols to relocation are to be entered here in Debugger console:

u-boot debugging. relocation.

Continue execution and it will stop at board_init_r function.

So, finally we got fully debuggable and controllable u-boot. Next time we will pass u-boot initialization procedure from start till the end to learn how it is.

U-boot initialization sequence

 

 

 

gdb load多個symbol的方法

load symbol可以用 add-symbol-file 指令

例如用
add-symbol-file rom.adx 0x8000
表示把 rom.adx 的symbol以 .text 為0x8000 base 載入 (其他section會跟著調整)
詳細功能可以在gdb用 help add-symbol-file 查
---------------------------------------------------

第1個adx檔用file
file xxx.adx (file會清掉之前的所有symbol)
第2個之後用add-symbol-file

add-symbol-file rom.adx 0x8000
其中0x8000是rom.adx檔的.text base

如果加入的不是.text而是其他section。
要個別打入section的名稱及位址。請參考下面的說明。

(gdb) help add-symbol-file
Load symbols from FILE, assuming FILE has been dynamically loaded.
Usage: add-symbol-file FILE ADDR [-s <SECT> <SECT_ADDR> -s <SECT> <SECT_ADDR> ..
.]
ADDR is the starting address of the file's text.
The optional arguments are section-name section-address pairs and
should be specified if the data and bss segments are not contiguous
with the text. SECT is a section name to be loaded at SECT_ADDR.
(gdb)

 

example

hylai@APC002 /cygdrive/d/mycode/patch
$ nds32le-elf-gdb.exe
GNU gdb (2012-03-16) 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-mingw32 --target=nds32le-elf".
source E:\Andestech\AndeSight200MCU\toolchains\nds32le-elf-newlib-v2\bin\.Andes
dbinit
(gdb) target remote:1234
Remote debugging using :1234
0x00016e02 in ?? ()
core0(gdb) target remote:1234
A program is being debugged already. Kill it? (y or n) y

Remote debugging using :1234
0x00016da6 in ?? ()
core0(gdb) file mainprog.adx
A program is being debugged already.
Are you sure you want to change the file? (y or n) y
Reading symbols from d:\mycode\patch\mainprog.adx...done.
core0(gdb) load
Loading section .nds32_init, size 0x4 lma 0x500000
Loading section .init, size 0xc lma 0x500004
Loading section .text, size 0x9518 lma 0x500010
Loading section .rodata, size 0x338 lma 0x509528
Loading section .eh_frame, size 0x34 lma 0x509860
Loading section .ctors, size 0x4 lma 0x509894
Loading section .dtors, size 0x4 lma 0x509898
Loading section .jcr, size 0x4 lma 0x50989c
Loading section .data, size 0x870 lma 0x5098a0
Loading section .sdata_w, size 0x38 lma 0x50a110
Loading section .sdata_b, size 0x3 lma 0x50a148
Loading section FUNC_TABLE, size 0xc lma 0x510000
Start address 0x500010, load size 41303
Transfer rate: 433 KB/sec, 2950 bytes/write.
core0(gdb) file patch.adx
A program is being debugged already.
Are you sure you want to change the file? (y or n) y

Load new symbol table from "d:\mycode\patch\patch.adx"? (y or n) y
Reading symbols from d:\mycode\patch\patch.adx...done.
core0(gdb) load
Loading section FUNC_TABLE, size 0xc lma 0x510000
Loading section FUNC_PATCH, size 0x38 lma 0x510020
Start address 0x500010, load size 68
Transfer rate: 544 bits in <1 sec, 34 bytes/write.
core0(gdb) file mainprog.adx
A program is being debugged already.
Are you sure you want to change the file? (y or n) y

Load new symbol table from "d:\mycode\patch\mainprog.adx"? (y or n) y
Reading symbols from d:\mycode\patch\mainprog.adx...done.
core0(gdb)add-symbol-file patch.adx 0x500000 -s FUNC_TABLE 0x510000 -s FUNC_PATCH 0x510020
add symbol table from file "patch.adx" at
.text_addr = 0x500000
FUNC_TABLE_addr = 0x510000
FUNC_PATCH_addr = 0x510020
(y or n) y
Reading symbols from d:\mycode\patch\patch.adx...warning: Lowest section in d:\
ycode\patch\patch.adx is FUNC_TABLE at 00510000
warning: section .text not found in d:\mycode\patch\patch.adx
done.
core0(gdb) set $pc=0x500000
core0(gdb) b main
Breakpoint 1 at 0x50010c: file ../main.c, line 20.
core0(gdb) c
Continuing.

Breakpoint 1, main () at ../main.c:20
20 printf("func1(30)=%d\n",jump_table.func_a(30));
core0(gdb) s
func1 (x=30) at ../main.c:28
28 return x*num1;
core0(gdb) n
29 }
core0(gdb) s
main () at ../main.c:21
21 printf("func2(30)=%d\n",jump_table.func_b(30));
core0(gdb) s
func2 (x=30) at ../patchprog.c:24
24 return x*num2*100;
core0(gdb)

 

 

 

 

https://www.codenong.com/33049201/

 

 

 

Examining the Symbol Table

The commands described in this chapter allow you to inquire about the symbols (names of variables, functions and types) defined in your program. This information is inherent in the text of your program and does not change as your program executes. GDB finds it in your program's symbol table, in the file indicated when you started GDB (see section Choosing files), or by one of the file-management commands (see section Commands to specify files).

Occasionally, you may need to refer to symbols that contain unusual characters, which GDB ordinarily treats as word delimiters. The most frequent case is in referring to static variables in other source files (see section Program variables). File names are recorded in object files as debugging symbols, but GDB would ordinarily parse a typical file name, like `foo.c', as the three words `foo' `.' `c'. To allow GDB to recognize `foo.c' as a single symbol, enclose it in single quotes; for example,

p 'foo.c'::x

looks up the value of x in the scope of the file `foo.c'.

info address symbol
Describe where the data for symbol is stored. For a register variable, this says which register it is kept in. For a non-register local variable, this prints the stack-frame offset at which the variable is always stored. Note the contrast with `print &symbol', which does not work at all for a register variable, and for a stack local variable prints the exact address of the current instantiation of the variable.
info symbol addr
Print the name of a symbol which is stored at the address addr. If no symbol is stored exactly at addr, GDB prints the nearest symbol and an offset from it:
(gdb) info symbol 0x54320
_initialize_vx + 396 in section .text
This is the opposite of the info address command. You can use it to find out the name of a variable or a function given its address.
whatis expr
Print the data type of expression exprexpr is not actually evaluated, and any side-effecting operations (such as assignments or function calls) inside it do not take place. See section Expressions.
whatis
Print the data type of $, the last value in the value history.
ptype typename
Print a description of data type typenametypename may be the name of a type, or for C code it may have the form `class class-name'`struct struct-tag'`union union-tag' or `enum enum-tag'.
ptype expr
ptype
Print a description of the type of expression exprptype differs from whatis by printing a detailed description, instead of just the name of the type. For example, for this variable declaration:
struct complex {double real; double imag;} v;
the two commands give this output:
(gdb) whatis v
type = struct complex
(gdb) ptype v
type = struct complex {
    double real;
    double imag;
}
As with whatis, using ptype without an argument refers to the type of $, the last value in the value history.
info types regexp
info types
Print a brief description of all types whose names match regexp (or all types in your program, if you supply no argument). Each complete typename is matched as though it were a complete line; thus, `i type value' gives information on all types in your program whose names include the string value, but `i type ^value$' gives information only on types whose complete name is value. This command differs from ptype in two ways: first, like whatis, it does not print a detailed description; second, it lists all source files where a type is defined.
info scope addr
List all the variables local to a particular scope. This command accepts a location--a function name, a source line, or an address preceded by a `*', and prints all the variables local to the scope defined by that location. For example:
(gdb) info scope command_line_handler
Scope for command_line_handler:
Symbol rl is an argument at stack/frame offset 8, length 4.
Symbol linebuffer is in static storage at address 0x150a18, length 4.
Symbol linelength is in static storage at address 0x150a1c, length 4.
Symbol p is a local variable in register $esi, length 4.
Symbol p1 is a local variable in register $ebx, length 4.
Symbol nline is a local variable in register $edx, length 4.
Symbol repeat is a local variable at frame offset -8, length 4.
This command is especially useful for determining what data to collect during a trace experiment, see section Tracepoint Action Lists.
info source
Show the name of the current source file--that is, the source file for the function containing the current point of execution--and the language it was written in.
info sources
Print the names of all source files in your program for which there is debugging information, organized into two lists: files whose symbols have already been read, and files whose symbols will be read when needed.
info functions
Print the names and data types of all defined functions.
info functions regexp
Print the names and data types of all defined functions whose names contain a match for regular expression regexp. Thus, `info fun step' finds all functions whose names include step`info fun ^step' finds those whose names start with step.
info variables
Print the names and data types of all variables that are declared outside of functions (i.e., excluding local variables).
info variables regexp
Print the names and data types of all variables (except for local variables) whose names contain a match for regular expression regexpSome systems allow individual object files that make up your program to be replaced without stopping and restarting your program. For example, in VxWorks you can simply recompile a defective object file and keep on running. If you are running on one of these systems, you can allow GDB to reload the symbols for automatically relinked modules:
set symbol-reloading on
Replace symbol definitions for the corresponding source file when an object file with a particular name is seen again.
set symbol-reloading off
Do not replace symbol definitions when encountering object files of the same name more than once. This is the default state; if you are not running on a system that permits automatic relinking of modules, you should leave symbol-reloading off, since otherwise GDB may discard symbols when linking large programs, that may contain several modules (from different directories or libraries) with the same name.
show symbol-reloading
Show the current on or off setting.
set opaque-type-resolution on
Tell GDB to resolve opaque types. An opaque type is a type declared as a pointer to a structclass, or union---for example, struct MyType *---that is used in one source file although the full declaration of struct MyType is in another source file. The default is on. A change in the setting of this subcommand will not take effect until the next time symbols for a file are loaded.
set opaque-type-resolution off
Tell GDB not to resolve opaque types. In this case, the type is printed as follows:
{<no data fields>}
show opaque-type-resolution
Show whether opaque types are resolved or not.
maint print symbols filename
maint print psymbols filename
maint print msymbols filename
Write a dump of debugging symbol data into the file filename. These commands are used to debug the GDB symbol-reading code. Only symbols with debugging data are included. If you use `maint print symbols', GDB includes all the symbols for which it has already collected full details: that is, filename reflects symbols for only those files whose symbols GDB has read. You can use the command info sources to find out which files these are. If you use `maint print psymbols' instead, the dump shows information about symbols that GDB only knows partially--that is, symbols defined in files that GDB has skimmed, but not yet read completely. Finally, `maint print msymbols' dumps just the minimal symbol information required for each object file from which GDB has read some symbols. See section Commands to specify files, for a discussion of how GDB reads symbols (in the description of symbol-file).
posted @ 2022-02-27 19:44  liujunhuasd  阅读(577)  评论(0编辑  收藏  举报