首页 > 解决方案 > 为什么当我使用 qemu 和 chroot 调试程序时 system() 的某些输出丢失

问题描述

最近,我尝试使用 QEMU 调试交叉编译的 arm 程序,但遇到了一个问题。

这是代码,很简单。

int main()  
{  
    printf("aaa\n");
    int  status;  
    status = system("./bin/ls"); 
    printf("Result of [system] = 0x%x\n", status);
}

当我使用命令启动程序时

spy@spy-virtual-machine:/usr/arm-linux-gnueabihf$ ./qemu-arm-static -L ./ ./a.out 

输出是:

aaa
bin              include          lib              test.c           qemu-arm-static  a.out            qemu-arm         shell.sh
Result of [system] = 0x0

但是当我像这样使用 chroot 启动程序时:

spy@spy-virtual-machine:/usr/arm-linux-gnueabihf$ sudo chroot ./ ./qemu-arm-static -L ./ ./a.out

输出结果是:

aaa
Result of [system] = 0x7f00

显然system("./bin/ls")没有按预期运行。

但是该./bin/ls命令可以通过 chroot & QEMU 运行:

spy@spy-virtual-machine:/usr/arm-linux-gnueabihf$ sudo chroot ./ ./qemu-arm-static -L ./ ./bin/ls
bin              include          lib              test.c           qemu-arm-static  a.out            qemu-arm         shell.sh

现在我完全糊涂了。谁能给我一个提示,以及system在使用chroot命令时我该怎么做才能获得正确的函数输出。

所有命令行输入输出都可以在这张图中找到: 命令行内容

标签: qemuchroot

解决方案


来自man 3 系统

system() 通过调用 /bin/sh -c 命令执行命令中指定的命令

因此,您需要在 chroot 内有一个工作 shell 才能成功调用 system()。

当这个程序在 qemu-arm-static 中运行时会发生以下情况:system()导致shellfork()后跟exec()。当你在没有 chroot 的情况下运行它时,这就是你的主机 (x86) shell。然后外壳调用fork()( ARM) exec()bin/ls我的理解是,只有在主机上注册了 ARM ELF 的 binfmt 处理程序,它才能成功。在这种情况下,注册的 qemu-arm 被加载并执行bin/ls

当您在 chroot 中执行相同操作时,无法访问主机 shell,因此system()导致exec()调用bin/sh(ARM)。看起来您的 binfmt 处理程序在 chroot 内无法访问,因此加载bin/sh失败并从system().

您可以在 /proc/sys/fs/binfmt_misc 中检查已注册的 binfmt 处理程序


推荐阅读