Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fatal Python error: failed to get random numbers to initialize Python

Fatal Python error: failed to get random numbers to initialize Python

Environment windows 10, VSC 15

Using CreateProcessA winapi and passing lpenvironment variable to run python with scripts. when lpenvironment is passed null, it works fine. If I set environment variable PATH and PYTHONPATH = "paths", and pass that LPSTR(env.c_Str()), it throws above error on running. The python version is 3.5.6

Any help?


Some more details.

  1. I run child process python.exe "C:\Program Files\endpoint\Python_ML\mlprocessor_server.py" using CreateProcessA WINAPI.
  2. I want to run child process with two environmental variables "PYTHONPATH" and "PATH". PYTHONPATH="C:\Program Files\endpoint\Python";"C:\Program Files\endpoint\Python\Scripts";"C:\Program Files\endpoint\Python\include";"C:\Program Files\endpoint\Python\Lib";"C:\Program Files\endpoint\Python\libs";"C:\Program Files\endpoint\Python\Lib\site-packages";"C:\Program Files\endpoint\Python_ML" PATH="C:\Program Files\endpoint\Python";"C:\Program Files\endpoint\Python\Lib";"C:\Program Files\endpoint\Python\Scripts";"C:\Program Files\endpoint\Python\libs"

For some reason, the 7th parameter in CreateProcessA fails, the python.exe runs successfully if it is null, or else it prints "Fatal Python error: failed to get random numbers to initialize Python".

The way I set the parameter as follows...

std::string Base = Configuration::getBasePath();

std::string environPython = Base;
environPython.append("\\Python;");
environPython.append(Base);
environPython.append("\\Python\\Scripts;");
environPython.append(Base);
environPython.append("\\Python\\include;");
environPython.append(Base);
environPython.append("\\Python\\Lib;");
environPython.append(Base);
environPython.append("\\Python\\libs;");
environPython.append(Base);
environPython.append("\\Python\\Lib\\site-packages;");
environPython.append(Base);
environPython.append("\\Python\\_ML;");
environPython.push_back('\0');


std::string environPath = Base;
environPath.append("\\Python;");
environPath.append(Base);
environPath.append("\\Python\\Lib;");
environPath.append(Base);
environPath.append("\\Python\\Scripts;");
environPath.append(Base);
environPath.append("\\Python\\libs;");
environPath.push_back('\0');

std::string cmd = Base;
cmd.append("\\Python\\python.exe");
std::string params = "\"";
params.append(cmd);
params.append("\" \"");
params.append(Base);
params.append("\\Python\\_ML\\mlprocessor_server.py\"");

std::map env = { { "PYTHONPATH", environPython.data() }, { "PATH", environPath.data() }};

// example for generating block of strings
std::vector<char> envBlock;
std::for_each(env.begin(), env.end(),
    [&envBlock](const std::pair<std::string, std::string> & p) {
    std::copy(p.first.begin(), p.first.end(), std::back_inserter(envBlock));
    envBlock.push_back('=');
    std::copy(p.second.begin(), p.second.end(),   std::back_inserter(envBlock));
    envBlock.push_back('\0');
}
);
envBlock.push_back('\0');

// feed this into ::CreateProcess()
LPVOID lpEnvironment = (LPVOID)envBlock.data();

bool result = CreateProcessA(cmd.c_str(), (LPSTR)params.c_str(), NULL, NULL, FALSE, CREATE_NO_WINDOW, lpEnvironment, NULL, &info, &pi);

The result is always true, python.exe is not shown up in task manager and gives Fatal Python error: failed to get random numbers to initialize Python.

If the lpEnvironment is NULL, python.exe is shown up in task manager.

like image 843
Sunder Ganesan Avatar asked Nov 22 '19 15:11

Sunder Ganesan


1 Answers

The environment you pass to CreateProcessA must include SYSTEMROOT, otherwise the Win32 API call CryptAcquireContext will fail when called inside python during initialization.

When passing in NULL as lpEnvironment, your new process inherits the environment of the calling process, which has SYSTEMROOT already defined.

like image 81
Joe Savage Avatar answered Nov 12 '22 22:11

Joe Savage