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