CentOS 7.5 和 Rocky Linux 8.4、Ubuntu 20.04 之间的不同 C++ fork() 行为

Different C++ fork() behavior between CentOS 7.5 & RockyLinux 8.4, Ubunu 20.04

我正在处理一些遗留代码。它在 CentOS 7 系统上运行良好。 args 数组在 Rocky 8.4 和 Ubuntu 20.04 系统上都被处理。我简化了问题并添加了打印语句。 execv() 正在启动另一个程序。进入 execv 的 args 搞砸了。如果没有 fork,代码将按预期工作。莫名其妙。

我有两个简单的测试程序,其中一个什么都不做。

test9.cpp

int main(){}

和test10.cpp

#include <iostream>
#include <string>
#include <vector>
#include <unistd.h>
int main()
{
   std::vector<std::string> stringArgs;
   std::string a{"./test9.x"};
   std::string b{"test10.cpp"};
   stringArgs.push_back(a);
   stringArgs.push_back(b);
        char* args[stringArgs.size()+1];
   if(fork() == 0){
        for(uint8_t i = 0; i < stringArgs.size(); i++) {
            std::string tmp(stringArgs[i]);
            args[i] = const_cast<char*>(tmp.c_str());
        std::cout << "\n\t"<<args[i]<<"'\n\n";
        }
        std::cout << "\n\t"<<args[0]<<"'\n\n";
        std::cout << "\n\t"<<args[1]<<"'\n\n";
        // last argument has to be NULL
        args[stringArgs.size()] = NULL;
    
        execv(args[0],&args[0]);
        std::cout << "\n\tERROR: Could not run '"<<args[0]<<"'\n\n";
   }
   else
    std::cout<<"parent\n";
}

g++ -o test9.x test9.cpp; g++ -o test10.x test10.cpp

在 CentOS 7 上我得到:

$ ./test10.x

    ./test9.x


    test10.cpp


    ./test9.x


    test10.cpp

    parent

在 Rocky Linux 8.4 和 Ubuntu 20.04 上我都明白了。注意 test9.x 在 for 循环后被 test10.cpp 替换。

./test10.x
parent

    ./test9.x


    test10.cpp


    test10.cpp


    test10.cpp


    ERROR: Could not run test10.cpp

这个循环

   for(uint8_t i = 0; i < stringArgs.size(); i++) {
        std::string tmp(stringArgs[i]);
        args[i] = const_cast<char*>(tmp.c_str());
        std::cout << "\n\t"<<args[i]<<"'\n\n";
    }

正在创建指向堆栈上的临时指针的数组,或一些内部实现定义的 std::string

部分

改为这样做

   for(uint8_t i = 0; i < stringArgs.size(); i++) {
        args[i] = strdup(stringArgs[i]);
        std::cout << "\n\t"<<args[i]<<"'\n\n";
    }