Home > Mobile >  Different C fork() behavior between CentOS 7.5 & RockyLinux 8.4, Ubunu 20.04
Different C fork() behavior between CentOS 7.5 & RockyLinux 8.4, Ubunu 20.04

Time:05-08

I'm working with some legacy code. It works fine on a CentOS 7 system. The args array gets hosed on both a Rocky 8.4 and Ubuntu 20.04 system. I've simplified the problem and added print statements. The execv() was launching another program. The args going into the execv get messed up. Without the fork, the code works as expected. Baffled.

I have two simple test programs, one of which does nothing.

test9.cpp

int main(){}

and 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

On the CentOS 7 I get:

$ ./test10.x

    ./test9.x


    test10.cpp


    ./test9.x


    test10.cpp

    parent

And on both Rocky Linux 8.4 and Ubuntu 20.04 I get this. Notice the test9.x gets replaced by test10.cpp after the for loop.

./test10.x
parent

    ./test9.x


    test10.cpp


    test10.cpp


    test10.cpp


    ERROR: Could not run test10.cpp

CodePudding user response:

THis loop

   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";
    }

is creating an array of pointers to a temporary on the stack, or some internal implementation defined part of std::string

do this instead

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