为什么 gdb 不能显示调试信息?
Why can't gdb show debug info?
这是我的 g++:
$ /usr/local/gcc-4.8.1-for-linux32/bin/i586-pc-linux-g++ -v
Using built-in specs.
COLLECT_GCC=/usr/local/gcc-4.8.1-for-linux32/bin/i586-pc-linux-g++
COLLECT_LTO_WRAPPER=/usr/local/gcc-4.8.1-for-linux32/libexec/gcc/i586-pc-linux/4.8.1/lto-wrapper
Target: i586-pc-linux
Configured with: ../gcc-4.8.1/configure --target=i586-pc-linux --build=i686-apple-darwin11 --prefix=/usr/local/gcc-4.8.1-for-linux32 --disable-multilib --enable-languages=c,c++ --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --disable-bootstrap
Thread model: posix
gcc version 4.8.1 (GCC)
gdb:
$ i386-linux-gdb -v
GNU gdb (GDB) 7.7.1
This GDB was configured as "--host=x86_64-apple-darwin15.5.0 --target=i386-linux".
CXX_FLAGS:
-ffreestanding -O0 -Wall -Wextra -fno-exceptions -fno-rtti -ggdb -nostdlib -std=c++11 -m32
生成 kernel.bin
:
/usr/local/gcc-4.8.1-for-linux32/bin/i586-pc-linux-g++ -I. -Iinclude -Ikernel -ffreestanding -O0 -Wall -Wextra -fno-exceptions -fno-rtti -ggdb -nostdlib -std=c++11 -m32 -e main -Ttext 0x100000 -o generated/kernel.bin generated/kernel/init/kernelMain.o generated/kernel/memoryManage/memoryManage.o
/usr/local/gcc-4.8.1-for-linux32/bin/i586-pc-linux-objdump -S -D generated/kernel.bin > generated/kernel.dump
我使用 qemu-i386 加载我的玩具 OS,然后我的引导加载程序将解析 kernel.bin
,将段放入内存。然后我在主机 OS (OS X 10.11) 中启动 gdb,执行:
file ./generated/kernel.bin
target remote localhost:1234
b initMemory
c
我可以在 memoryManage.o
.
中的函数 initMemory
处成功停止
8: x/i 0x100000 + $eip
0x100010 <initMemory()>: push %ebp
然而,当我执行 n
或 s
或 p
时,它不起作用。我只能用 si
ni
(gdb) n
Cannot find bounds of current function
(gdb) s
Cannot find bounds of current function
(gdb) p memoryInfoAddr
No symbol "memoryInfoAddr" in current context.
我该如何解决这个问题?是i586 g++和i386 gdb不匹配导致的,还是gcc 4.8.1和gdb 7.7.1不匹配导致的?
终于找到问题所在了。 gdb 使用 %eip
来查找指令,但是在我的内核中它应该使用 %cs:%eip
。将 %cs
设置为 0
后,gdb 按预期工作。
这是我的 g++:
$ /usr/local/gcc-4.8.1-for-linux32/bin/i586-pc-linux-g++ -v
Using built-in specs.
COLLECT_GCC=/usr/local/gcc-4.8.1-for-linux32/bin/i586-pc-linux-g++
COLLECT_LTO_WRAPPER=/usr/local/gcc-4.8.1-for-linux32/libexec/gcc/i586-pc-linux/4.8.1/lto-wrapper
Target: i586-pc-linux
Configured with: ../gcc-4.8.1/configure --target=i586-pc-linux --build=i686-apple-darwin11 --prefix=/usr/local/gcc-4.8.1-for-linux32 --disable-multilib --enable-languages=c,c++ --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --disable-bootstrap
Thread model: posix
gcc version 4.8.1 (GCC)
gdb:
$ i386-linux-gdb -v
GNU gdb (GDB) 7.7.1
This GDB was configured as "--host=x86_64-apple-darwin15.5.0 --target=i386-linux".
CXX_FLAGS:
-ffreestanding -O0 -Wall -Wextra -fno-exceptions -fno-rtti -ggdb -nostdlib -std=c++11 -m32
生成 kernel.bin
:
/usr/local/gcc-4.8.1-for-linux32/bin/i586-pc-linux-g++ -I. -Iinclude -Ikernel -ffreestanding -O0 -Wall -Wextra -fno-exceptions -fno-rtti -ggdb -nostdlib -std=c++11 -m32 -e main -Ttext 0x100000 -o generated/kernel.bin generated/kernel/init/kernelMain.o generated/kernel/memoryManage/memoryManage.o
/usr/local/gcc-4.8.1-for-linux32/bin/i586-pc-linux-objdump -S -D generated/kernel.bin > generated/kernel.dump
我使用 qemu-i386 加载我的玩具 OS,然后我的引导加载程序将解析 kernel.bin
,将段放入内存。然后我在主机 OS (OS X 10.11) 中启动 gdb,执行:
file ./generated/kernel.bin
target remote localhost:1234
b initMemory
c
我可以在 memoryManage.o
.
initMemory
处成功停止
8: x/i 0x100000 + $eip
0x100010 <initMemory()>: push %ebp
然而,当我执行 n
或 s
或 p
时,它不起作用。我只能用 si
ni
(gdb) n
Cannot find bounds of current function
(gdb) s
Cannot find bounds of current function
(gdb) p memoryInfoAddr
No symbol "memoryInfoAddr" in current context.
我该如何解决这个问题?是i586 g++和i386 gdb不匹配导致的,还是gcc 4.8.1和gdb 7.7.1不匹配导致的?
终于找到问题所在了。 gdb 使用 %eip
来查找指令,但是在我的内核中它应该使用 %cs:%eip
。将 %cs
设置为 0
后,gdb 按预期工作。