qemu - 为什么当我使用 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
命令时我该怎么做才能获得正确的函数输出。
所有命令行输入输出都可以在这张图中找到: 命令行内容
解决方案
来自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 处理程序
推荐阅读
- apache-spark - google Spark-BigQuery-Connector 如何利用 BigQuery Storage API?
- r - 如何使用 grep 功能进行搜索?
- performance - 性能测试环境
- javascript - 在Javascript中迭代嵌套数组的浅拷贝
- r - 如何用 R 计算观测值之间的比率
- ruby - Ruby FFI 回调返回值
- android - 使用 Chrome 进行 USB 调试仅在 Android Studio 打开时有效
- amazon-web-services - 在 lambda 函数中访问 aws appsync api 的环境特定表名
- python - Python MD4 函数无法像在线 MD4 哈希生成器那样生成哈希码
- azure-devops - 在构建队列时扩展模板验证