8303814: getLastErrorString should avoid charset conversions

Reviewed-by: naoto, cjplummer, rriggs
This commit is contained in:
Daniel Jeliński 2023-03-14 17:18:56 +00:00
parent 830fd41346
commit baf11e734f
8 changed files with 106 additions and 129 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1994, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -204,16 +204,11 @@ writeBytes(JNIEnv *env, jobject this, jbyteArray bytes,
void void
throwFileNotFoundException(JNIEnv *env, jstring path) throwFileNotFoundException(JNIEnv *env, jstring path)
{ {
char buf[256];
size_t n;
jobject x; jobject x;
jstring why = NULL; jstring why;
n = getLastErrorString(buf, sizeof(buf)); why = getLastErrorString(env);
if (n > 0) { JNU_CHECK_EXCEPTION(env);
why = JNU_NewStringPlatform(env, buf);
CHECK_NULL(why);
}
x = JNU_NewObjectByName(env, x = JNU_NewObjectByName(env,
"java/io/FileNotFoundException", "java/io/FileNotFoundException",
"(Ljava/lang/String;Ljava/lang/String;)V", "(Ljava/lang/String;Ljava/lang/String;)V",

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -103,17 +103,13 @@ JNIEXPORT void JNICALL
JNU_ThrowByNameWithLastError(JNIEnv *env, const char *name, JNU_ThrowByNameWithLastError(JNIEnv *env, const char *name,
const char *defaultDetail) const char *defaultDetail)
{ {
char buf[256]; jstring s = getLastErrorString(env);
size_t n = getLastErrorString(buf, sizeof(buf));
if (n > 0) { if (s != NULL) {
jstring s = JNU_NewStringPlatform(env, buf); jobject x = JNU_NewObjectByName(env, name,
if (s != NULL) { "(Ljava/lang/String;)V", s);
jobject x = JNU_NewObjectByName(env, name, if (x != NULL) {
"(Ljava/lang/String;)V", s); (*env)->Throw(env, x);
if (x != NULL) {
(*env)->Throw(env, x);
}
} }
} }
if (!(*env)->ExceptionOccurred(env)) { if (!(*env)->ExceptionOccurred(env)) {
@ -129,48 +125,44 @@ JNIEXPORT void JNICALL
JNU_ThrowByNameWithMessageAndLastError JNU_ThrowByNameWithMessageAndLastError
(JNIEnv *env, const char *name, const char *message) (JNIEnv *env, const char *name, const char *message)
{ {
char buf[256];
size_t n = getLastErrorString(buf, sizeof(buf));
size_t messagelen = message == NULL ? 0 : strlen(message); size_t messagelen = message == NULL ? 0 : strlen(message);
if (n > 0) { jstring s = getLastErrorString(env);
jstring s = JNU_NewStringPlatform(env, buf); if (s != NULL) {
if (s != NULL) { jobject x = NULL;
jobject x = NULL; if (messagelen > 0) {
if (messagelen) { jstring s2 = NULL;
jstring s2 = NULL; size_t messageextlen = messagelen + 4;
size_t messageextlen = messagelen + 4; char *str1 = (char *)malloc((messageextlen) * sizeof(char));
char *str1 = (char *)malloc((messageextlen) * sizeof(char)); if (str1 == NULL) {
if (str1 == 0) { JNU_ThrowOutOfMemoryError(env, 0);
JNU_ThrowOutOfMemoryError(env, 0); return;
return; }
} jio_snprintf(str1, messageextlen, " (%s)", message);
jio_snprintf(str1, messageextlen, " (%s)", message); s2 = (*env)->NewStringUTF(env, str1);
s2 = (*env)->NewStringUTF(env, str1); free(str1);
free(str1); JNU_CHECK_EXCEPTION(env);
if (s2 != NULL) {
jstring s3 = JNU_CallMethodByName(
env, NULL, s, "concat",
"(Ljava/lang/String;)Ljava/lang/String;",
s2).l;
(*env)->DeleteLocalRef(env, s2);
JNU_CHECK_EXCEPTION(env); JNU_CHECK_EXCEPTION(env);
if (s2 != NULL) { if (s3 != NULL) {
jstring s3 = JNU_CallMethodByName( (*env)->DeleteLocalRef(env, s);
env, NULL, s, "concat", s = s3;
"(Ljava/lang/String;)Ljava/lang/String;",
s2).l;
(*env)->DeleteLocalRef(env, s2);
JNU_CHECK_EXCEPTION(env);
if (s3 != NULL) {
(*env)->DeleteLocalRef(env, s);
s = s3;
}
} }
} }
x = JNU_NewObjectByName(env, name, "(Ljava/lang/String;)V", s); }
if (x != NULL) { x = JNU_NewObjectByName(env, name, "(Ljava/lang/String;)V", s);
(*env)->Throw(env, x); if (x != NULL) {
} (*env)->Throw(env, x);
} }
} }
if (!(*env)->ExceptionOccurred(env)) { if (!(*env)->ExceptionOccurred(env)) {
if (messagelen) { if (messagelen > 0) {
JNU_ThrowByName(env, name, message); JNU_ThrowByName(env, name, message);
} else { } else {
JNU_ThrowByName(env, name, "no further information"); JNU_ThrowByName(env, name, "no further information");

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -336,8 +336,7 @@ void* getProcessHandle();
void buildJniFunctionName(const char *sym, const char *cname, void buildJniFunctionName(const char *sym, const char *cname,
char *jniEntryName); char *jniEntryName);
JNIEXPORT size_t JNICALL jstring getLastErrorString(JNIEnv *env);
getLastErrorString(char *buf, size_t len);
JNIEXPORT int JNICALL JNIEXPORT int JNICALL
getErrorString(int err, char *buf, size_t len); getErrorString(int err, char *buf, size_t len);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1995, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1995, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -529,7 +529,7 @@ addMetaName(jzfile *zip, const char *name, int length)
static void static void
freeMetaNames(jzfile *zip) freeMetaNames(jzfile *zip)
{ {
if (zip->metanames) { if (zip->metanames != NULL) {
jint i; jint i;
for (i = 0; i < zip->metacount; i++) for (i = 0; i < zip->metacount; i++)
free(zip->metanames[i]); free(zip->metanames[i]);
@ -764,7 +764,8 @@ readCEN(jzfile *zip, jint knownTotal)
* Opens a zip file with the specified mode. Returns the jzfile object * Opens a zip file with the specified mode. Returns the jzfile object
* or NULL if an error occurred. If a zip error occurred then *pmsg will * or NULL if an error occurred. If a zip error occurred then *pmsg will
* be set to the error message text if pmsg != 0. Otherwise, *pmsg will be * be set to the error message text if pmsg != 0. Otherwise, *pmsg will be
* set to NULL. Caller is responsible to free the error message. * set to NULL. Caller doesn't need to free the error message.
* The error message, if set, points to a static thread-safe buffer.
*/ */
jzfile * jzfile *
ZIP_Open_Generic(const char *name, char **pmsg, int mode, jlong lastModified) ZIP_Open_Generic(const char *name, char **pmsg, int mode, jlong lastModified)
@ -790,7 +791,7 @@ ZIP_Open_Generic(const char *name, char **pmsg, int mode, jlong lastModified)
* zip files, or NULL if the file is not in the cache. If the name is longer * zip files, or NULL if the file is not in the cache. If the name is longer
* than PATH_MAX or a zip error occurred then *pmsg will be set to the error * than PATH_MAX or a zip error occurred then *pmsg will be set to the error
* message text if pmsg != 0. Otherwise, *pmsg will be set to NULL. Caller * message text if pmsg != 0. Otherwise, *pmsg will be set to NULL. Caller
* is responsible to free the error message. * doesn't need to free the error message.
*/ */
jzfile * jzfile *
ZIP_Get_From_Cache(const char *name, char **pmsg, jlong lastModified) ZIP_Get_From_Cache(const char *name, char **pmsg, jlong lastModified)
@ -803,13 +804,13 @@ ZIP_Get_From_Cache(const char *name, char **pmsg, jlong lastModified)
} }
/* Clear zip error message */ /* Clear zip error message */
if (pmsg != 0) { if (pmsg != NULL) {
*pmsg = NULL; *pmsg = NULL;
} }
if (strlen(name) >= PATH_MAX) { if (strlen(name) >= PATH_MAX) {
if (pmsg) { if (pmsg != NULL) {
*pmsg = strdup("zip file name too long"); *pmsg = "zip file name too long";
} }
return NULL; return NULL;
} }
@ -834,7 +835,7 @@ ZIP_Get_From_Cache(const char *name, char **pmsg, jlong lastModified)
* Reads data from the given file descriptor to create a jzfile, puts the * Reads data from the given file descriptor to create a jzfile, puts the
* jzfile in a cache, and returns that jzfile. Returns NULL in case of error. * jzfile in a cache, and returns that jzfile. Returns NULL in case of error.
* If a zip error occurs, then *pmsg will be set to the error message text if * If a zip error occurs, then *pmsg will be set to the error message text if
* pmsg != 0. Otherwise, *pmsg will be set to NULL. Caller is responsible to * pmsg != 0. Otherwise, *pmsg will be set to NULL. Caller doesn't need to
* free the error message. * free the error message.
*/ */
@ -863,8 +864,8 @@ ZIP_Put_In_Cache0(const char *name, ZFILE zfd, char **pmsg, jlong lastModified,
zip->lastModified = lastModified; zip->lastModified = lastModified;
if (zfd == -1) { if (zfd == -1) {
if (pmsg && getLastErrorString(errbuf, sizeof(errbuf)) > 0) if (pmsg != NULL)
*pmsg = strdup(errbuf); *pmsg = "ZFILE_Open failed";
freeZip(zip); freeZip(zip);
return NULL; return NULL;
} }
@ -877,12 +878,12 @@ ZIP_Put_In_Cache0(const char *name, ZFILE zfd, char **pmsg, jlong lastModified,
len = zip->len = IO_Lseek(zfd, 0, SEEK_END); len = zip->len = IO_Lseek(zfd, 0, SEEK_END);
if (len <= 0) { if (len <= 0) {
if (len == 0) { /* zip file is empty */ if (len == 0) { /* zip file is empty */
if (pmsg) { if (pmsg != NULL) {
*pmsg = strdup("zip file is empty"); *pmsg = "zip file is empty";
} }
} else { /* error */ } else { /* error */
if (pmsg && getLastErrorString(errbuf, sizeof(errbuf)) > 0) if (pmsg != NULL)
*pmsg = strdup(errbuf); *pmsg = "IO_Lseek failed";
} }
ZFILE_Close(zfd); ZFILE_Close(zfd);
freeZip(zip); freeZip(zip);
@ -892,10 +893,9 @@ ZIP_Put_In_Cache0(const char *name, ZFILE zfd, char **pmsg, jlong lastModified,
zip->zfd = zfd; zip->zfd = zfd;
if (readCEN(zip, -1) < 0) { if (readCEN(zip, -1) < 0) {
/* An error occurred while trying to read the zip file */ /* An error occurred while trying to read the zip file */
if (pmsg != 0) { if (pmsg != NULL) {
/* Set the zip error message */ /* Set the zip error message */
if (zip->msg != NULL) *pmsg = zip->msg;
*pmsg = strdup(zip->msg);
} }
freeZip(zip); freeZip(zip);
return NULL; return NULL;
@ -918,10 +918,6 @@ JNIEXPORT jzfile *
ZIP_Open(const char *name, char **pmsg) ZIP_Open(const char *name, char **pmsg)
{ {
jzfile *file = ZIP_Open_Generic(name, pmsg, O_RDONLY, 0); jzfile *file = ZIP_Open_Generic(name, pmsg, O_RDONLY, 0);
if (file == NULL && pmsg != NULL && *pmsg != NULL) {
free(*pmsg);
*pmsg = "Zip file open error";
}
return file; return file;
} }
@ -1138,8 +1134,8 @@ ZIP_FreeEntry(jzfile *jz, jzentry *ze)
if (last != NULL) { if (last != NULL) {
/* Free the previously cached jzentry */ /* Free the previously cached jzentry */
free(last->name); free(last->name);
if (last->extra) free(last->extra); free(last->extra);
if (last->comment) free(last->comment); free(last->comment);
free(last); free(last);
} }
} }
@ -1517,7 +1513,7 @@ ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entryname)
msg = zip->msg; msg = zip->msg;
ZIP_Unlock(zip); ZIP_Unlock(zip);
if (n == -1) { if (n == -1) {
if (msg == 0) { if (msg == NULL) {
getErrorString(errno, tmpbuf, sizeof(tmpbuf)); getErrorString(errno, tmpbuf, sizeof(tmpbuf));
msg = tmpbuf; msg = tmpbuf;
} }
@ -1534,7 +1530,7 @@ ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entryname)
if ((msg == NULL) || (*msg == 0)) { if ((msg == NULL) || (*msg == 0)) {
msg = zip->msg; msg = zip->msg;
} }
if (msg == 0) { if (msg == NULL) {
getErrorString(errno, tmpbuf, sizeof(tmpbuf)); getErrorString(errno, tmpbuf, sizeof(tmpbuf));
msg = tmpbuf; msg = tmpbuf;
} }
@ -1554,7 +1550,7 @@ ZIP_InflateFully(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pm
z_stream strm; z_stream strm;
memset(&strm, 0, sizeof(z_stream)); memset(&strm, 0, sizeof(z_stream));
*pmsg = 0; /* Reset error message */ *pmsg = NULL; /* Reset error message */
if (inflateInit2(&strm, MAX_WBITS) != Z_OK) { if (inflateInit2(&strm, MAX_WBITS) != Z_OK) {
*pmsg = strm.msg; *pmsg = strm.msg;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -60,12 +60,13 @@ void buildJniFunctionName(const char *sym, const char *cname,
} }
} }
JNIEXPORT size_t JNICALL jstring
getLastErrorString(char *buf, size_t len) getLastErrorString(JNIEnv *env)
{ {
if (errno == 0 || len < 1) return 0; char buf[256] = {0};
getErrorString(errno, buf, len); if (errno == 0) return NULL;
return strlen(buf); getErrorString(errno, buf, sizeof(buf));
return (buf[0] != 0) ? JNU_NewStringPlatform(env, buf) : NULL;
} }
JNIEXPORT int JNICALL JNIEXPORT int JNICALL

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -63,34 +63,34 @@ void buildJniFunctionName(const char *sym, const char *cname,
return; return;
} }
JNIEXPORT size_t JNICALL jstring
getLastErrorString(char *buf, size_t len) { getLastErrorString(JNIEnv *env) {
#define BUFSIZE 256
DWORD errval; DWORD errval;
WCHAR buf[BUFSIZE];
if ((errval = GetLastError()) != 0) { if ((errval = GetLastError()) != 0) {
// DOS error // DOS error
size_t n = (size_t)FormatMessage( jsize n = FormatMessageW(
FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, NULL,
errval, errval,
0, 0,
buf, buf,
(DWORD)len, BUFSIZE,
NULL); NULL);
if (n > 3) { if (n > 3) {
// Drop final '.', CR, LF // Drop final '.', CR, LF
if (buf[n - 1] == '\n') n--; if (buf[n - 1] == L'\n') n--;
if (buf[n - 1] == '\r') n--; if (buf[n - 1] == L'\r') n--;
if (buf[n - 1] == '.') n--; if (buf[n - 1] == L'.') n--;
buf[n] = '\0'; buf[n] = L'\0';
} }
return n; jstring s = (*env)->NewString(env, buf, n);
return s;
} }
return NULL;
// C runtime error that has no corresponding DOS error code
if (errno == 0 || len < 1) return 0;
return strerror_s(buf, len, errno);
} }
JNIEXPORT int JNICALL JNIEXPORT int JNICALL

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -49,7 +49,7 @@ Java_sun_nio_ch_FileDispatcherImpl_read0(JNIEnv *env, jclass clazz, jobject fdo,
HANDLE h = (HANDLE)(handleval(env, fdo)); HANDLE h = (HANDLE)(handleval(env, fdo));
if (h == INVALID_HANDLE_VALUE) { if (h == INVALID_HANDLE_VALUE) {
JNU_ThrowIOExceptionWithLastError(env, "Invalid handle"); JNU_ThrowIOException(env, "Invalid handle");
return IOS_THROWN; return IOS_THROWN;
} }
result = ReadFile(h, /* File handle to read */ result = ReadFile(h, /* File handle to read */
@ -85,7 +85,7 @@ Java_sun_nio_ch_FileDispatcherImpl_readv0(JNIEnv *env, jclass clazz, jobject fdo
HANDLE h = (HANDLE)(handleval(env, fdo)); HANDLE h = (HANDLE)(handleval(env, fdo));
if (h == INVALID_HANDLE_VALUE) { if (h == INVALID_HANDLE_VALUE) {
JNU_ThrowIOExceptionWithLastError(env, "Invalid handle"); JNU_ThrowIOException(env, "Invalid handle");
return IOS_THROWN; return IOS_THROWN;
} }
@ -131,7 +131,7 @@ Java_sun_nio_ch_FileDispatcherImpl_pread0(JNIEnv *env, jclass clazz, jobject fdo
OVERLAPPED ov; OVERLAPPED ov;
if (h == INVALID_HANDLE_VALUE) { if (h == INVALID_HANDLE_VALUE) {
JNU_ThrowIOExceptionWithLastError(env, "Invalid handle"); JNU_ThrowIOException(env, "Invalid handle");
return IOS_THROWN; return IOS_THROWN;
} }
@ -199,9 +199,12 @@ Java_sun_nio_ch_FileDispatcherImpl_write0(JNIEnv *env, jclass clazz, jobject fdo
len, /* number of bytes to write */ len, /* number of bytes to write */
&written, /* receives number of bytes written */ &written, /* receives number of bytes written */
lpOv); /* overlapped struct */ lpOv); /* overlapped struct */
} else {
JNU_ThrowIOException(env, "Invalid handle");
return IOS_THROWN;
} }
if ((h == INVALID_HANDLE_VALUE) || (result == 0)) { if (result == 0) {
JNU_ThrowIOExceptionWithLastError(env, "Write failed"); JNU_ThrowIOExceptionWithLastError(env, "Write failed");
return IOS_THROWN; return IOS_THROWN;
} }
@ -248,9 +251,12 @@ Java_sun_nio_ch_FileDispatcherImpl_writev0(JNIEnv *env, jclass clazz, jobject fd
break; break;
} }
} }
} else {
JNU_ThrowIOException(env, "Invalid handle");
return IOS_THROWN;
} }
if ((h == INVALID_HANDLE_VALUE) || (result == 0)) { if (result == 0) {
JNU_ThrowIOExceptionWithLastError(env, "Write failed"); JNU_ThrowIOExceptionWithLastError(env, "Write failed");
return IOS_THROWN; return IOS_THROWN;
} }
@ -268,6 +274,10 @@ Java_sun_nio_ch_FileDispatcherImpl_pwrite0(JNIEnv *env, jclass clazz, jobject fd
LARGE_INTEGER currPos; LARGE_INTEGER currPos;
OVERLAPPED ov; OVERLAPPED ov;
if (h == INVALID_HANDLE_VALUE) {
JNU_ThrowIOException(env, "Invalid handle");
return IOS_THROWN;
}
currPos.QuadPart = 0; currPos.QuadPart = 0;
result = SetFilePointerEx(h, currPos, &currPos, FILE_CURRENT); result = SetFilePointerEx(h, currPos, &currPos, FILE_CURRENT);
if (result == 0) { if (result == 0) {
@ -285,7 +295,7 @@ Java_sun_nio_ch_FileDispatcherImpl_pwrite0(JNIEnv *env, jclass clazz, jobject fd
&written, /* receives number of bytes written */ &written, /* receives number of bytes written */
&ov); /* position to write at */ &ov); /* position to write at */
if ((h == INVALID_HANDLE_VALUE) || (result == 0)) { if (result == 0) {
JNU_ThrowIOExceptionWithLastError(env, "Write failed"); JNU_ThrowIOExceptionWithLastError(env, "Write failed");
return IOS_THROWN; return IOS_THROWN;
} }
@ -341,7 +351,7 @@ Java_sun_nio_ch_FileDispatcherImpl_force0(JNIEnv *env, jobject this,
} }
} }
} else { } else {
JNU_ThrowIOExceptionWithLastError(env, "Force failed"); JNU_ThrowIOException(env, "Invalid handle");
return IOS_THROWN; return IOS_THROWN;
} }
return 0; return 0;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -82,11 +82,9 @@ JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_asm_Disassembler_load_1library(JNIE
jclass disclass, jclass disclass,
jstring libname_s) { jstring libname_s) {
uintptr_t func = 0; uintptr_t func = 0;
const char *error_message = NULL;
const char *libname = NULL; const char *libname = NULL;
#ifdef _WINDOWS #ifdef _WINDOWS
char buffer[JVM_MAXPATHLEN];
HINSTANCE hsdis_handle = (HINSTANCE) NULL; HINSTANCE hsdis_handle = (HINSTANCE) NULL;
#else #else
void* hsdis_handle = NULL; void* hsdis_handle = NULL;
@ -104,8 +102,7 @@ JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_asm_Disassembler_load_1library(JNIE
func = (uintptr_t)GetProcAddress(hsdis_handle, "decode_instructions_virtual"); func = (uintptr_t)GetProcAddress(hsdis_handle, "decode_instructions_virtual");
} }
if (func == 0) { if (func == 0) {
getLastErrorString(buffer, sizeof(buffer)); JNU_ThrowByNameWithLastError(env, "sun/jvm/hotspot/debugger/DebuggerException", "GetProcAddress failed");
error_message = buffer;
} }
#else #else
hsdis_handle = dlopen(libname, RTLD_LAZY | RTLD_GLOBAL); hsdis_handle = dlopen(libname, RTLD_LAZY | RTLD_GLOBAL);
@ -113,24 +110,11 @@ JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_asm_Disassembler_load_1library(JNIE
func = (uintptr_t)dlsym(hsdis_handle, "decode_instructions_virtual"); func = (uintptr_t)dlsym(hsdis_handle, "decode_instructions_virtual");
} }
if (func == 0) { if (func == 0) {
error_message = dlerror(); JNU_ThrowByName(env, "sun/jvm/hotspot/debugger/DebuggerException", dlerror());
} }
#endif #endif
(*env)->ReleaseStringUTFChars(env, libname_s, libname); (*env)->ReleaseStringUTFChars(env, libname_s, libname);
if (func == 0) {
/* Couldn't find entry point. error_message should contain some
* platform dependent error message.
*/
jstring s = JNU_NewStringPlatform(env, error_message);
if (s != NULL) {
jobject x = JNU_NewObjectByName(env, "sun/jvm/hotspot/debugger/DebuggerException", "(Ljava/lang/String;)V", s);
if (x != NULL) {
(*env)->Throw(env, x);
}
}
}
return (jlong)func; return (jlong)func;
} }