exec如何改变exec'ed程序的行为

时间:2010-03-22 20:08:47

标签: c++ linux crash exec

我试图追踪一个非常奇怪的崩溃。奇怪的是,有人发现了一种我无法解释的解决方法。

解决方法是这个小程序,我将其称为“跑步者”:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

int main(int argc, char *argv[])
{
    if (argc == 1)
    {
        fprintf(stderr, "Usage: %s prog [args ...]\n", argv[0]);
        return 1;
    }

    execvp(argv[1], argv + 1);

    fprintf(stderr, "execv failed: %s\n", strerror(errno));

    // If exec returns because the program is not found or we
    // don't have the appropriate permission
    return 255;
}

正如您所看到的,所有这些程序都使用execvp来替换自己的其他程序。

程序在从命令行直接调用时崩溃:

/path/to/prog args  # this crashes

但通过我的跑步者垫片间接调用它时工作正常:

/path/to/runner /path/to/prog args   # works successfully

对于我的生活,我可以弄清楚如何让额外的exec改变正在运行的程序的行为(因为你可以看到该程序不会改变环境)。

崩溃的一些背景知识。崩溃本身发生在C ++运行时。具体来说,当程序执行throw时,崩溃版本错误地认为没有匹配的catch(尽管有)并调用terminate。当我通过跑步者调用程序时,异常被正确捕获。

我的问题是,为什么额外的exec改变了exec'ed程序的行为?

5 个答案:

答案 0 :(得分:3)

跑步者加载的.so文件可能导致runee正常工作。尝试ldd'ing每个二进制文件,看看是否有任何库加载不同的版本/位置。

答案 1 :(得分:1)

也许被调用的程序有内存泄漏。尝试使用valgrind或其他一些内存检查工具运行它。在您遇到内存错误之后,其他所有内容都是未定义的行为(因此一切都会发生)。

答案 2 :(得分:0)

在黑暗中拍摄:双执行可能会改变RAM中环境变量的顺序。

环境是一个带指针的内存结构;内核将该结构复制到新进程的地址空间中。 RAM中元素的实际顺序可能会在该复制期间发生变化(环境变量不是语义排序的,但RAM中的地址有顺序)。使用两个exec(),订单可能会被修改两次。

RAM中字符串排序的变化发现了一个bug有些怪异,但是发生了一些奇怪的事情。

答案 3 :(得分:0)

我想知道你是否将argv [0]中的不同内容传递给shell。我无法从上面的内容中看到,但是你可能将argv [0]设置为程序的实际第一个参数,而shell则将其设置为其被调用的名称(例如,完整或短路径) )

答案 4 :(得分:0)

我猜你可以在'working'和'crashing'版本之间比较两件事 - 打开文件描述符和信号处理程序 - 因为它们会被exec传递。

我看不出它们是怎样的问题/不同,但可能值得消除它们。