summaryrefslogtreecommitdiff
path: root/mysql-test/lib/My/SafeProcess
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@mariadb.com>2017-10-13 19:40:06 +0000
committerVladislav Vaintroub <wlad@mariadb.com>2017-10-13 22:24:25 +0000
commitbcd1a08eb3379431ac2a66be9a09f753a70a5fde (patch)
tree32653e238b41f8691ea37520d44256fb7fb52715 /mysql-test/lib/My/SafeProcess
parent9ee840cd0a86145e014252fe106d9798b2abc08b (diff)
downloadmariadb-git-bcd1a08eb3379431ac2a66be9a09f753a70a5fde.tar.gz
Fix mtr to create a process dump on Window for hanging or looping processes
Diffstat (limited to 'mysql-test/lib/My/SafeProcess')
-rw-r--r--mysql-test/lib/My/SafeProcess/CMakeLists.txt1
-rw-r--r--mysql-test/lib/My/SafeProcess/safe_kill_win.cc82
2 files changed, 81 insertions, 2 deletions
diff --git a/mysql-test/lib/My/SafeProcess/CMakeLists.txt b/mysql-test/lib/My/SafeProcess/CMakeLists.txt
index ec93f94a3e8..ff842f3468f 100644
--- a/mysql-test/lib/My/SafeProcess/CMakeLists.txt
+++ b/mysql-test/lib/My/SafeProcess/CMakeLists.txt
@@ -25,6 +25,7 @@ SET(INSTALL_ARGS
IF (WIN32)
MYSQL_ADD_EXECUTABLE(my_safe_process safe_process_win.cc ${INSTALL_ARGS})
MYSQL_ADD_EXECUTABLE(my_safe_kill safe_kill_win.cc ${INSTALL_ARGS})
+ TARGET_LINK_LIBRARIES(my_safe_kill dbghelp psapi)
ELSE()
MYSQL_ADD_EXECUTABLE(my_safe_process safe_process.cc ${INSTALL_ARGS})
ENDIF()
diff --git a/mysql-test/lib/My/SafeProcess/safe_kill_win.cc b/mysql-test/lib/My/SafeProcess/safe_kill_win.cc
index 2ac29c61bc7..e5ec33af571 100644
--- a/mysql-test/lib/My/SafeProcess/safe_kill_win.cc
+++ b/mysql-test/lib/My/SafeProcess/safe_kill_win.cc
@@ -25,6 +25,80 @@
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
+#include <psapi.h>
+#include <DbgHelp.h>
+
+static int create_dump(DWORD pid)
+{
+ char path[MAX_PATH];
+ char working_dir[MAX_PATH];
+ int ret= -1;
+ HANDLE process= INVALID_HANDLE_VALUE;
+ HANDLE file= INVALID_HANDLE_VALUE;
+ char *p;
+
+ process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, (DWORD)pid);
+ if (!process)
+ {
+ fprintf(stderr,"safe_kill : cannot open process pid=%u to create dump, last error %u\n",
+ pid, GetLastError());
+ goto exit;
+ }
+
+ DWORD size = MAX_PATH;
+ if (QueryFullProcessImageName(process, 0, path, &size) == 0)
+ {
+ fprintf(stderr,"safe_kill : cannot read process path for pid %u, last error %u\n",
+ pid, GetLastError());
+ goto exit;
+ }
+
+ if ((p = strrchr(path, '.')) == 0)
+ p= path + strlen(path);
+
+ strncpy(p, ".dmp", path + MAX_PATH - p);
+
+ /* Create dump in current directory.*/
+ const char *filename= strrchr(path, '\\');
+ if (filename == 0)
+ filename = path;
+ else
+ filename++;
+
+ if (!GetCurrentDirectory(MAX_PATH, working_dir))
+ {
+ fprintf(stderr, "GetCurrentDirectory failed, last error %u",GetLastError());
+ goto exit;
+ }
+
+ file = CreateFile(filename, GENERIC_READ | GENERIC_WRITE,
+ 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+
+ if (file == INVALID_HANDLE_VALUE)
+ {
+ fprintf(stderr,"safe_kill : CreateFile() failed for file %s, working dir %s, last error = %u\n",
+ filename, working_dir, GetLastError());
+ goto exit;
+ }
+
+ if (!MiniDumpWriteDump(process, pid, file, MiniDumpNormal, 0,0,0))
+ {
+ fprintf(stderr, "Failed to write minidump to %s, working dir %s, last error %u\n",
+ filename, working_dir, GetLastError());
+ goto exit;
+ }
+
+ ret = 0;
+ fprintf(stderr, "Minidump written to %s, directory %s\n", filename, working_dir);
+
+exit:
+ if(process!= 0 && process != INVALID_HANDLE_VALUE)
+ CloseHandle(process);
+
+ if (file != 0 && file != INVALID_HANDLE_VALUE)
+ CloseHandle(file);
+ return ret;
+}
int main(int argc, const char** argv )
{
@@ -37,12 +111,16 @@ int main(int argc, const char** argv )
signal(SIGBREAK, SIG_IGN);
signal(SIGTERM, SIG_IGN);
- if (argc != 2) {
- fprintf(stderr, "safe_kill <pid>\n");
+ if ((argc != 2 && argc != 3) || (argc == 3 && strcmp(argv[2],"dump"))) {
+ fprintf(stderr, "safe_kill <pid> [dump]\n");
exit(2);
}
pid= atoi(argv[1]);
+ if (argc == 3)
+ {
+ return create_dump(pid);
+ }
_snprintf(safe_process_name, sizeof(safe_process_name),
"safe_process[%d]", pid);