Gdb 如何在QEMU用户模式下调试动态链接的可执行文件?

Gdb 如何在QEMU用户模式下调试动态链接的可执行文件?,gdb,qemu,Gdb,Qemu,例如,对于ARM,如果我以静态方式编译,则所有工作正常: sudo apt-get install gdb-multiarch gcc-arm-linux-gnueabihf qemu-user printf ' #include <stdio.h> #include <stdlib.h> int main() { puts("hello world"); return EXIT_SUCCESS; } ' > hello_world.c arm-

例如,对于ARM,如果我以静态方式编译,则所有工作正常:

sudo apt-get install gdb-multiarch gcc-arm-linux-gnueabihf qemu-user
printf '
#include <stdio.h>
#include <stdlib.h>

int main() {
    puts("hello world");
    return EXIT_SUCCESS;
}
' >  hello_world.c
arm-linux-gnueabihf-gcc -ggdb3 -static -o hello_world hello_world.c
qemu-arm -L /usr/arm-linux-gnueabihf -g 1234 ./hello_world
这让我在
main
,我可以像往常一样看到源代码和步骤调试

但是,如果我删除
-static
,并保持其他所有内容不变,我的断点将永远不会被命中,程序将一直运行到完成:

The target architecture is assumed to be arm
Reading symbols from hello_world...done.
Remote debugging using localhost:1234
Reading symbols from /usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3...(no debugging symbols found)...done.
0xff7b3b80 in ?? () from /usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3
Breakpoint 1 at 0x50c: file hello_world.c, line 5.
Continuing.
[Inferior 1 (Remote target) exited normally]
可执行文件本身工作正常,但是:

qemu-arm -L /usr/arm-linux-gnueabihf ./hello_world
印刷品:

hello world
我已经看到了:但是它没有专门涉及动态链接的可执行文件

在Ubuntu 18.04、gdb multiarch 8.1-0ubuntu3、gcc arm linux gnueabihf 4:7.3.0-3ubuntu2、qemu用户1:2.11+dfsg-1ubuntu7.3上测试

编辑:使用原始的交叉工具ng设置

作为一项明智的检查,我尝试使用crosstool ng获得一个干净的工具链,它成功了:

git clone https://github.com/crosstool-ng/crosstool-ng
cd crosstool-ng
git checkout d5900debd397b8909d9cafeb9a1093fb7a5dc6e6
export CT_PREFIX="$(pwd)/.build/ct_prefix"
./bootstrap
./configure --enable-local
./ct-ng arm-cortex_a15-linux-gnueabihf
# Has to be older than host kernel, which is 4.15.
printf "
CT_LINUX_V_4_14=y
CT_LINUX_VERSION=\"4.14.0\"
" >> .config
./ct-ng oldconfig
env -u LD_LIBRARY_PATH time ./ct-ng build -j`nproc`
cd ..
crosstool-ng/.build/ct_prefix/arm-cortex_a15-linux-gnueabihf/bin/arm-cortex_a15-linux-gnueabihf-gcc -ggdb3 -o hello_world hello_world.c -ggdb3 -static -o hello_world hello_world.c
qemu-arm -L crosstool-ng/.build/ct_prefix/arm-cortex_a15-linux-gnueabihf/arm-cortex_a15-linux-gnueabihf/sysroot -g 1234 ./hello_world
在另一个外壳上:

./.build/ct_prefix/arm-cortex_a15-linux-gnueabihf/bin/arm-cortex_a15-linux-gnueabihf-gdb \
  -q --nh \
  -ex 'set architecture arm' \
  -ex 'set sysroot crosstool-ng/.build/ct_prefix/arm-cortex_a15-linux-gnueabihf/arm-cortex_a15-linux-gnueabihf/sysroot' \
  -ex 'file hello_world' \
  -ex 'target remote localhost:1234' \
  -ex 'break main' \
  -ex continue \
;

它也适用于发行版提供的gdb multiarch

故障是由于
-pie-fpie
造成的,并且有一个关于它的错误报告,位于:

显式设置
-no pie-fno pie
使其在crosstool ng和Ubuntu主机上都能工作

区别在于Ubuntu one的GCC构建默认使用
-fpie
,而我的crosstool ng构建没有

这可以通过以下方式进行检查:

gcc -v
在主机GCC上包含以下内容:

--enable-default-pie
但不是在crosstool ng构建中

我是如何发现的:前几天我在玩
-fpie
,我注意到
.text
地址在这种情况下非常小:

然后,我看到,使用打包的工具链,中断地址非常小,并创建了链接

--enable-default-pie