Info about the project: I am creating a C++ console application that manages a Minecraft server by listening to port activity. When server port is pinged, it starts the server and then periodically checks if there are established connections on that port. If none, the server is shut down and app goes into listening mode once again.
The problem arises when the server is stopped. Somehow my main console app is getting killed by the child server process and I can't seem to find out how and why or any solutions to this.
My console app creates a new cmd.exe child process that runs a "java -jar server.jar" command when starting the server. When stopping the server a simple "stop" message is written to the standard input of the child process. This all works fine and the java server stops.
However as soon as the child process exits, the console app unexpectedly crashes and the Windows "Program has stopped working." dialog appears. The curious thing is that I have tested the application on my programming laptop that runs Windows 10 and it runs without any issues there both in release and debug mode. My server machine is running Windows 7 however, so it seems to somehow be a Windows 7 problem.
Now there's no code I can really show you since it's the java and cmd.exe child process performing the exit and I of course didn't code the server.jar file. But I will attach an image link of the console when it crashes just for fun.
The child process does not have a separate window, it inherits handles from the parent console app and writes to the parent's STDOUT so messages from the child show in the main app's console.
I have tried starting the child process with CREATE_NEW_PROCESS_GROUP flag, still crashes.
I have tried ignoring SIGINT and SIGTERM signals, still crashes.
I have also verified that the application doesn't start execution of the commands following the server shutdown call (writing stop message to stdin of server process) so they can't be the problem.
If anyone has any tips or ideas about what could be the issue I'm all ears. Thanks!
Console application crashes, Windows "Program has stopped working." dialog is not shown on picture.
EDIT:
Okay, so I created a minimal reproducible example. Here is all the needed code (for C++ main function):
//security attributes for pipesSECURITY_ATTRIBUTES saAttr;saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);saAttr.bInheritHandle = TRUE;saAttr.lpSecurityDescriptor = NULL;//handles for child standard input/outputHANDLE child_stdin_rd = NULL;HANDLE child_stdin_wr = NULL;if (!CreatePipe(&child_stdin_rd, &child_stdin_wr, &saAttr, 0)) return -1;if (!SetHandleInformation(child_stdin_wr, HANDLE_FLAG_INHERIT, 0)) return -1;STARTUPINFOW startupInfo;ZeroMemory(&startupInfo, sizeof(STARTUPINFOW));startupInfo.cb = sizeof(STARTUPINFOW);startupInfo.hStdInput = child_stdin_rd;startupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);startupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);startupInfo.dwFlags |= STARTF_USESTDHANDLES;PROCESS_INFORMATION processInfo;ZeroMemory(&processInfo, sizeof(PROCESS_INFORMATION));//cmd.exe pathwstring exepath = L"c:\\windows\\system32\\cmd.exe";//cmd command to start serverwstring command = L"cmd.exe /c java -Xms1G -Xmx4G -jar server.jar nogui";LPWSTR com = new wchar_t[command.size() + 1];copy(command.begin(), command.end(), com);com[command.size()] = 0;if (!CreateProcessW(exepath.c_str(), com, 0, 0, TRUE, CREATE_NEW_PROCESS_GROUP, 0, 0, &startupInfo, &processInfo)) return -1;//sleep for 1 min, letting server start upthis_thread::sleep_for(chrono::minutes(1));//command to stop serverstring stopCmd = "stop\n\0";DWORD stopCmdByteSize = stopCmd.size() * sizeof(char);if (!WriteFile(child_stdin_wr, stopCmd.c_str(), stopCmdByteSize, 0, 0)) return -1;CloseHandle(processInfo.hProcess);CloseHandle(processInfo.hThread);CloseHandle(child_stdin_wr);
To reproduce this, your machine would need to be running Windows 7 and in the same folder as the application must be a Minecraft server.jar file (version 1.15.2 at time of writing this) which you can get from their website. Also, the server might need some setting up first, running it for the first time by double-clicking .jar file creates all needed server files, you must open "eula.txt" and accept the EULA by changing eula=false
to eula=true
. Then the server should be good to go.
Like stated before, I didn't code the server.jar file and thus do not know the complete behavior of the java server program.