Fix mtr to create a process dump on Window for hanging or looping processes
This commit is contained in:
parent
9ee840cd0a
commit
bcd1a08eb3
@ -336,9 +336,14 @@ sub start_kill {
|
|||||||
|
|
||||||
sub dump_core {
|
sub dump_core {
|
||||||
my ($self)= @_;
|
my ($self)= @_;
|
||||||
return if IS_WINDOWS;
|
|
||||||
my $pid= $self->{SAFE_PID};
|
my $pid= $self->{SAFE_PID};
|
||||||
die "Can't get core from not started process" unless defined $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");
|
_verbose("Sending ABRT to $self");
|
||||||
kill ("ABRT", $pid);
|
kill ("ABRT", $pid);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -25,6 +25,7 @@ SET(INSTALL_ARGS
|
|||||||
IF (WIN32)
|
IF (WIN32)
|
||||||
MYSQL_ADD_EXECUTABLE(my_safe_process safe_process_win.cc ${INSTALL_ARGS})
|
MYSQL_ADD_EXECUTABLE(my_safe_process safe_process_win.cc ${INSTALL_ARGS})
|
||||||
MYSQL_ADD_EXECUTABLE(my_safe_kill safe_kill_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()
|
ELSE()
|
||||||
MYSQL_ADD_EXECUTABLE(my_safe_process safe_process.cc ${INSTALL_ARGS})
|
MYSQL_ADD_EXECUTABLE(my_safe_process safe_process.cc ${INSTALL_ARGS})
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
@ -25,6 +25,80 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdlib.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 )
|
int main(int argc, const char** argv )
|
||||||
{
|
{
|
||||||
@ -37,12 +111,16 @@ int main(int argc, const char** argv )
|
|||||||
signal(SIGBREAK, SIG_IGN);
|
signal(SIGBREAK, SIG_IGN);
|
||||||
signal(SIGTERM, SIG_IGN);
|
signal(SIGTERM, SIG_IGN);
|
||||||
|
|
||||||
if (argc != 2) {
|
if ((argc != 2 && argc != 3) || (argc == 3 && strcmp(argv[2],"dump"))) {
|
||||||
fprintf(stderr, "safe_kill <pid>\n");
|
fprintf(stderr, "safe_kill <pid> [dump]\n");
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
pid= atoi(argv[1]);
|
pid= atoi(argv[1]);
|
||||||
|
|
||||||
|
if (argc == 3)
|
||||||
|
{
|
||||||
|
return create_dump(pid);
|
||||||
|
}
|
||||||
_snprintf(safe_process_name, sizeof(safe_process_name),
|
_snprintf(safe_process_name, sizeof(safe_process_name),
|
||||||
"safe_process[%d]", pid);
|
"safe_process[%d]", pid);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user