Path: blob/master/test/hotspot/jtreg/vmTestbase/vm/share/ProcessUtils.cpp
41153 views
/*1* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/22#include "jni.h"23#include "native_thread.h"24#ifdef _WIN3225#include <windows.h>26#include <process.h>27#include <vdmdbg.h>28#include <dbghelp.h>29#else /* _WIN32 */30#include <unistd.h>31#include <signal.h>32#endif /* _WIN32 */33#include "jni_tools.h"3435extern "C" {3637/*38* Class: vm_share_ProcessUtils39* Method: sendSignal40* Signature: ()Z41*/42JNIEXPORT jboolean JNICALL Java_vm_share_ProcessUtils_sendSignal43(JNIEnv *env, jclass klass, jint signalNum) {44#ifdef _WIN3245/* TODO TODO TODO46int dw;47LPVOID lpMsgBuf;48if (!GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0)) {49dw = GetLastError();50FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,51NULL,52dw,53MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),54(LPTSTR) &lpMsgBuf,550,56NULL57);58printf("%s\n", (LPTSTR)lpMsgBuf);59LocalFree(lpMsgBuf);60return JNI_FALSE;61}62*/63return JNI_TRUE;64#else /* _WIN32 */65if (kill(getpid(), signalNum) < 0)66return JNI_FALSE;67return JNI_TRUE;68#endif /* _WIN32 */69}7071/*72* Class: vm_share_ProcessUtils73* Method: sendCtrlBreak74* Signature: ()Z75*/76JNIEXPORT jboolean JNICALL Java_vm_share_ProcessUtils_sendCtrlBreak77(JNIEnv *env, jclass klass) {78#ifdef _WIN3279int dw;80LPVOID lpMsgBuf;81if (!GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0)) {82dw = GetLastError();83FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,84NULL,85dw,86MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),87(LPTSTR) &lpMsgBuf,880,89NULL90);91printf("%s\n", (LPTSTR)lpMsgBuf);92LocalFree(lpMsgBuf);93return JNI_FALSE;94}95return JNI_TRUE;96#else /* _WIN32 */97if (kill(getpid(), SIGQUIT) < 0)98return JNI_FALSE;99return JNI_TRUE;100#endif /* _WIN32 */101}102103#ifdef _WIN32104static BOOL (WINAPI *_MiniDumpWriteDump) (HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION,105PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION);106void reportLastError(const char *msg) {107long errcode = GetLastError();108if (errcode != 0) {109DWORD len = 0;110char *buf;111size_t n = (size_t)FormatMessage(112FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_ALLOCATE_BUFFER,113NULL,114errcode,1150,116(LPSTR) &buf,117(DWORD)len,118NULL);119if (n > 3) {120/* Drop final '.', CR, LF */121if (buf[n - 1] == '\n') n--;122if (buf[n - 1] == '\r') n--;123if (buf[n - 1] == '.') n--;124buf[n] = '\0';125}126printf("%s: %s\n", msg, buf);127LocalFree(buf);128}129}130131#endif /* _WIN32 */132133jboolean doDumpCore() {134#ifdef _WIN32135char path[MAX_PATH];136DWORD size;137DWORD pathLen = (DWORD) sizeof(path);138HINSTANCE dbghelp;139MINIDUMP_EXCEPTION_INFORMATION* pmei;140141HANDLE hProcess = GetCurrentProcess();142DWORD processId = GetCurrentProcessId();143HANDLE dumpFile;144MINIDUMP_TYPE dumpType;145static const char* cwd;146static const char* name = "DBGHELP.DLL";147148printf("# TEST: creating Windows minidump...\n");149size = GetSystemDirectory(path, pathLen);150if (size > 0) {151strcat(path, "\\");152strcat(path, name);153dbghelp = LoadLibrary(path);154if (dbghelp == NULL)155reportLastError("Load DBGHELP.DLL from system directory");156} else {157printf("GetSystemDirectory returned 0\n");158}159160// try Windows directory161if (dbghelp == NULL) {162size = GetWindowsDirectory(path, pathLen);163if (size > 6) {164strcat(path, "\\");165strcat(path, name);166dbghelp = LoadLibrary(path);167if (dbghelp == NULL) {168reportLastError("Load DBGHELP.DLL from Windows directory");169}170}171}172if (dbghelp == NULL) {173printf("Failed to load DBGHELP.DLL\n");174return JNI_FALSE;175}176177_MiniDumpWriteDump =178(BOOL(WINAPI *)(HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION,179PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION))180GetProcAddress(dbghelp, "MiniDumpWriteDump");181182if (_MiniDumpWriteDump == NULL) {183printf("Failed to find MiniDumpWriteDump() in module dbghelp.dll");184return JNI_FALSE;185}186dumpType = (MINIDUMP_TYPE)(MiniDumpWithFullMemory | MiniDumpWithHandleData);187188// Older versions of dbghelp.h doesn't contain all the dumptypes we want, dbghelp.h with189// API_VERSION_NUMBER 11 or higher contains the ones we want though190#if API_VERSION_NUMBER >= 11191dumpType = (MINIDUMP_TYPE)(dumpType | MiniDumpWithFullMemoryInfo | MiniDumpWithThreadInfo |192MiniDumpWithUnloadedModules);193#endif194195dumpFile = CreateFile("core.mdmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);196197if (dumpFile == INVALID_HANDLE_VALUE) {198reportLastError("Failed to create file for dumping");199return JNI_FALSE;200}201pmei = NULL;202203204// Older versions of dbghelp.dll (the one shipped with Win2003 for example) may not support all205// the dump types we really want. If first call fails, lets fall back to just use MiniDumpWithFullMemory then.206if (_MiniDumpWriteDump(hProcess, processId, dumpFile, dumpType, pmei, NULL, NULL) == FALSE &&207_MiniDumpWriteDump(hProcess, processId, dumpFile, (MINIDUMP_TYPE)MiniDumpWithFullMemory, pmei, NULL, NULL) == FALSE) {208reportLastError("Call to MiniDumpWriteDump() failed");209return JNI_FALSE;210}211212CloseHandle(dumpFile);213printf("# TEST: minidump created\n");214// Emulate Unix behaviour - exit process.215ExitProcess(137);216217return JNI_TRUE;218#else /* _WIN32 */219if (kill(getpid(), SIGSEGV) < 0)220return JNI_FALSE;221return JNI_TRUE;222#endif /* _WIN32 */223224}225226/*227* Class: vm_share_ProcessUtils228* Method: dumpCore229* Signature: ()Z230*/231JNIEXPORT jboolean JNICALL Java_vm_share_ProcessUtils_dumpCore232(JNIEnv *env, jclass klass)233{234return doDumpCore();235}236237/*238* Class: vm_share_ProcessUtils239* Method: getPid240* Signature: ()I241*/242JNIEXPORT jint JNICALL Java_vm_share_ProcessUtils_getPid243(JNIEnv *env, jclass klass) {244#ifdef _WIN32245return _getpid();246#else /* _WIN32 */247return getpid();248#endif /* _WIN32 */249}250251252/*253* Class: vm_share_ProcessUtils254* Method: getPid255* Signature: ()I256*/257JNIEXPORT jint JNICALL Java_vm_share_ProcessUtils_getWindowsPid258(JNIEnv *env, jclass klass, jlong handle) {259#ifdef _WIN32260return GetProcessId((HANDLE) handle);261#else /* _WIN32 */262return -1;263#endif /* _WIN32 */264}265266}267268269