diff options
-rw-r--r-- | mysql-test/lib/My/SafeProcess.pm | 7 | ||||
-rw-r--r-- | mysql-test/lib/My/SafeProcess/CMakeLists.txt | 1 | ||||
-rw-r--r-- | mysql-test/lib/My/SafeProcess/safe_kill_win.cc | 82 |
3 files changed, 87 insertions, 3 deletions
diff --git a/mysql-test/lib/My/SafeProcess.pm b/mysql-test/lib/My/SafeProcess.pm index f3ee772cca3..3260a6ed593 100644 --- a/mysql-test/lib/My/SafeProcess.pm +++ b/mysql-test/lib/My/SafeProcess.pm @@ -336,9 +336,14 @@ sub start_kill { sub dump_core { my ($self)= @_; - return if IS_WINDOWS; my $pid= $self->{SAFE_PID}; die "Can't get core from not started process" unless defined $pid; + + if (IS_WINDOWS) { + system("$safe_kill $pid dump"); + return 1; + } + _verbose("Sending ABRT to $self"); kill ("ABRT", $pid); return 1; 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); |