提交 390a2806 编写于 作者: D dholmes

7200297: agent code does not handle multiple boot library path elements correctly

Summary: When bug 6819213 was fixed it enabled sun.boot.library.path property to contain multiple paths. Code in agents does not handle multiple paths when attempting to find dependent shared libs.
Reviewed-by: dholmes, sspitsyn, dsamersoff
Contributed-by: NBill Pittore <bill.pittore@oracle.com>
上级 20bc15e8
/*
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -37,6 +37,7 @@
#include "debugLoop.h"
#include "bag.h"
#include "invoker.h"
#include "sys.h"
/* How the options get to OnLoad: */
#define XDEBUG "-Xdebug"
......@@ -201,6 +202,8 @@ Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
jint jvmtiCompileTimeMajorVersion;
jint jvmtiCompileTimeMinorVersion;
jint jvmtiCompileTimeMicroVersion;
char *boot_path = NULL;
char npt_lib[MAXPATHLEN];
/* See if it's already loaded */
if ( gdata!=NULL && gdata->isLoaded==JNI_TRUE ) {
......@@ -227,18 +230,6 @@ Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
vmInitialized = JNI_FALSE;
gdata->vmDead = JNI_FALSE;
/* Npt and Utf function init */
NPT_INITIALIZE(&(gdata->npt), NPT_VERSION, NULL);
if (gdata->npt == NULL) {
ERROR_MESSAGE(("JDWP: unable to initialize NPT library"));
return JNI_ERR;
}
gdata->npt->utf = (gdata->npt->utfInitialize)(NULL);
if (gdata->npt->utf == NULL) {
ERROR_MESSAGE(("JDWP: UTF function initialization failed"));
return JNI_ERR;
}
/* Get the JVMTI Env, IMPORTANT: Do this first! For jvmtiAllocate(). */
error = JVM_FUNC_PTR(vm,GetEnv)
(vm, (void **)&(gdata->jvmti), JVMTI_VERSION_1);
......@@ -277,6 +268,24 @@ Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
forceExit(1); /* Kill entire process, no core dump wanted */
}
JVMTI_FUNC_PTR(gdata->jvmti, GetSystemProperty)
(gdata->jvmti, (const char *)"sun.boot.library.path",
&boot_path);
dbgsysBuildLibName(npt_lib, sizeof(npt_lib), boot_path, NPT_LIBNAME);
/* Npt and Utf function init */
NPT_INITIALIZE(npt_lib, &(gdata->npt), NPT_VERSION, NULL);
jvmtiDeallocate(boot_path);
if (gdata->npt == NULL) {
ERROR_MESSAGE(("JDWP: unable to initialize NPT library"));
return JNI_ERR;
}
gdata->npt->utf = (gdata->npt->utfInitialize)(NULL);
if (gdata->npt->utf == NULL) {
ERROR_MESSAGE(("JDWP: UTF function initialization failed"));
return JNI_ERR;
}
/* Parse input options */
if (!parseOptions(options)) {
/* No message necessary, should have been printed out already */
......
/*
* Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -70,8 +70,13 @@ vprint_message(FILE *fp, const char *prefix, const char *suffix,
len = (int)strlen((char*)utf8buf);
/* Convert to platform encoding (ignore errors, dangerous area) */
(void)(gdata->npt->utf8ToPlatform)(gdata->npt->utf,
utf8buf, len, pbuf, MAX_MESSAGE_LEN);
if (gdata->npt != NULL) {
(void)(gdata->npt->utf8ToPlatform)(gdata->npt->utf,
utf8buf, len, pbuf, MAX_MESSAGE_LEN);
} else {
/* May be called before NPT is initialized so don't fault */
strncpy(pbuf, (char*)utf8buf, len);
}
(void)fprintf(fp, "%s%s%s", prefix, pbuf, suffix);
}
......
/*
* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -144,7 +144,9 @@ loadTransport(char *name, jdwpTransportEnv **transportPtr)
/* First, look in sun.boot.library.path. This should find the standard
* dt_socket and dt_shmem transport libraries, or any library
* that was delivered with the J2SE.
* Note: Java property sun.boot.library.path contains a single directory.
* Note: Since 6819213 fixed, Java property sun.boot.library.path can
* contain multiple paths. Dll_dir is the first entry and
* -Dsun.boot.library.path entries are appended.
*/
libdir = gdata->property_sun_boot_library_path;
if (libdir == NULL) {
......
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -65,6 +65,7 @@
#include "jni.h"
#include "jvmti.h"
#include "classfile_constants.h"
#include "jvm_md.h"
#ifndef SKIP_NPT
#include "npt.h" /* To get NptEnv for doing character conversions */
......
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -1899,6 +1899,7 @@ load_library(char *name)
*/
getSystemProperty("sun.boot.library.path", &boot_path);
md_build_library_name(lname, FILENAME_MAX, boot_path, name);
jvmtiDeallocate(boot_path);
handle = md_load_library(lname, err_buf, (int)sizeof(err_buf));
if ( handle == NULL ) {
/* This may be necessary on Windows. */
......@@ -1941,6 +1942,9 @@ lookup_library_symbol(void *library, char **symbols, int nsymbols)
JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
{
char *boot_path = NULL;
char npt_lib[JVM_MAXPATHLEN];
/* See if it's already loaded */
if ( gdata!=NULL && gdata->isLoaded==JNI_TRUE ) {
HPROF_ERROR(JNI_TRUE, "Cannot load this JVM TI agent twice, check your java command line for duplicate hprof options.");
......@@ -1957,9 +1961,15 @@ Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
gdata->jvm = vm;
/* Get the JVMTI environment */
getJvmti();
#ifndef SKIP_NPT
getSystemProperty("sun.boot.library.path", &boot_path);
/* Load in NPT library for character conversions */
NPT_INITIALIZE(&(gdata->npt), NPT_VERSION, NULL);
md_build_library_name(npt_lib, sizeof(npt_lib), boot_path, NPT_LIBNAME);
jvmtiDeallocate(boot_path);
NPT_INITIALIZE(npt_lib, &(gdata->npt), NPT_VERSION, NULL);
if ( gdata->npt == NULL ) {
HPROF_ERROR(JNI_TRUE, "Cannot load npt library");
}
......@@ -1969,9 +1979,6 @@ Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
}
#endif
/* Get the JVMTI environment */
getJvmti();
/* Lock needed to protect debug_malloc() code, which is not MT safe */
#ifdef DEBUG
gdata->debug_malloc_lock = createRawMonitor("HPROF debug_malloc lock");
......
......@@ -54,6 +54,32 @@
#define LIB_SUFFIX "so"
#endif
static void dll_build_name(char* buffer, size_t buflen,
const char* pname, const char* fname) {
// Based on os_solaris.cpp
char *path_sep = PATH_SEPARATOR;
char *pathname = (char *)pname;
while (strlen(pathname) > 0) {
char *p = strchr(pathname, *path_sep);
if (p == NULL) {
p = pathname + strlen(pathname);
}
/* check for NULL path */
if (p == pathname) {
continue;
}
(void)snprintf(buffer, buflen, "%.*s/lib%s." LIB_SUFFIX, (p - pathname),
pathname, fname);
if (access(buffer, F_OK) == 0) {
break;
}
pathname = p + 1;
*buffer = '\0';
}
}
/*
* create a string for the JNI native function name by adding the
* appropriate decorations.
......@@ -76,16 +102,16 @@ dbgsysBuildLibName(char *holder, int holderlen, char *pname, char *fname)
{
const int pnamelen = pname ? strlen(pname) : 0;
*holder = '\0';
/* Quietly truncate on buffer overflow. Should be an error. */
if (pnamelen + (int)strlen(fname) + 10 > holderlen) {
*holder = '\0';
return;
}
if (pnamelen == 0) {
(void)snprintf(holder, holderlen, "lib%s." LIB_SUFFIX, fname);
} else {
(void)snprintf(holder, holderlen, "%s/lib%s." LIB_SUFFIX, pname, fname);
dll_build_name(holder, holderlen, pname, fname);
}
}
......
......@@ -380,6 +380,31 @@ md_ntohl(unsigned l)
return ntohl(l);
}
static void dll_build_name(char* buffer, size_t buflen,
const char* pname, const char* fname) {
// Loosely based on os_solaris.cpp
char *pathname = (char *)pname;
while (strlen(pathname) > 0) {
char *p = strchr(pathname, ':');
if (p == NULL) {
p = pathname + strlen(pathname);
}
/* check for NULL path */
if (p == pathname) {
continue;
}
(void)snprintf(buffer, buflen, "%.*s/lib%s" JNI_LIB_SUFFIX,
(p - pathname), pathname, fname);
if (access(buffer, F_OK) == 0) {
break;
}
pathname = p + 1;
*buffer = '\0';
}
}
/* Create the actual fill filename for a dynamic library. */
void
md_build_library_name(char *holder, int holderlen, char *pname, char *fname)
......@@ -389,9 +414,9 @@ md_build_library_name(char *holder, int holderlen, char *pname, char *fname)
/* Length of options directory location. */
pnamelen = pname ? strlen(pname) : 0;
*holder = '\0';
/* Quietly truncate on buffer overflow. Should be an error. */
if (pnamelen + (int)strlen(fname) + 10 > holderlen) {
*holder = '\0';
return;
}
......@@ -399,7 +424,7 @@ md_build_library_name(char *holder, int holderlen, char *pname, char *fname)
if (pnamelen == 0) {
(void)snprintf(holder, holderlen, "lib%s" JNI_LIB_SUFFIX, fname);
} else {
(void)snprintf(holder, holderlen, "%s/lib%s" JNI_LIB_SUFFIX, pname, fname);
dll_build_name(holder, holderlen, pname, fname);
}
}
......
......@@ -36,14 +36,14 @@
#define NPT_LIBNAME "npt"
#define NPT_INITIALIZE(pnpt,version,options) \
#define NPT_INITIALIZE(path,pnpt,version,options) \
{ \
void *_handle; \
void *_sym; \
\
if ( (pnpt) == NULL ) NPT_ERROR("NptEnv* is NULL"); \
*(pnpt) = NULL; \
_handle = dlopen(JNI_LIB_NAME(NPT_LIBNAME), RTLD_LAZY); \
_handle = dlopen(path, RTLD_LAZY); \
if ( _handle == NULL ) NPT_ERROR("Cannot open library"); \
_sym = dlsym(_handle, "nptInitialize"); \
if ( _sym == NULL ) NPT_ERROR("Cannot find nptInitialize"); \
......
/*
* Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -32,11 +32,42 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <io.h>
#include "sys.h"
#include "path_md.h"
static void dll_build_name(char* buffer, size_t buflen,
const char* pname, const char* fname) {
// Based on os_windows.cpp
char *path_sep = PATH_SEPARATOR;
char *pathname = (char *)pname;
while (strlen(pathname) > 0) {
char *p = strchr(pathname, *path_sep);
if (p == NULL) {
p = pathname + strlen(pathname);
}
/* check for NULL path */
if (p == pathname) {
continue;
}
if (*(p-1) == ':' || *(p-1) == '\\') {
(void)_snprintf(buffer, buflen, "%.*s%s.dll", (p - pathname),
pathname, fname);
} else {
(void)_snprintf(buffer, buflen, "%.*s\\%s.dll", (p - pathname),
pathname, fname);
}
if (_access(buffer, 0) == 0) {
break;
}
pathname = p + 1;
*buffer = '\0';
}
}
/*
* From system_md.c v1.54
*/
......@@ -80,20 +111,17 @@ void
dbgsysBuildLibName(char *holder, int holderlen, char *pname, char *fname)
{
const int pnamelen = pname ? (int)strlen(pname) : 0;
const char c = (pnamelen > 0) ? pname[pnamelen-1] : 0;
*holder = '\0';
/* Quietly truncates on buffer overflow. Should be an error. */
if (pnamelen + (int)strlen(fname) + 10 > holderlen) {
*holder = '\0';
return;
}
if (pnamelen == 0) {
sprintf(holder, "%s.dll", fname);
} else if (c == ':' || c == '\\') {
sprintf(holder, "%s%s.dll", pname, fname);
} else {
sprintf(holder, "%s\\%s.dll", pname, fname);
dll_build_name(holder, holderlen, pname, fname);
}
}
......
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -367,28 +367,53 @@ get_last_error_string(char *buf, int len)
return 0;
}
static void dll_build_name(char* buffer, size_t buflen,
const char* pname, const char* fname) {
// Loosley based on os_windows.cpp
char *pathname = (char *)pname;
while (strlen(pathname) > 0) {
char *p = strchr(pathname, ';');
if (p == NULL) {
p = pathname + strlen(pathname);
}
/* check for NULL path */
if (p == pathname) {
continue;
}
if (*(p-1) == ':' || *(p-1) == '\\') {
(void)_snprintf(buffer, buflen, "%.*s%s.dll", (p - pathname),
pathname, fname);
} else {
(void)_snprintf(buffer, buflen, "%.*s\\%s.dll", (p - pathname),
pathname, fname);
}
if (_access(buffer, 0) == 0) {
break;
}
pathname = p + 1;
*buffer = '\0';
}
}
/* Build a machine dependent library name out of a path and file name. */
void
md_build_library_name(char *holder, int holderlen, char *pname, char *fname)
{
int pnamelen;
char c;
pnamelen = pname ? (int)strlen(pname) : 0;
c = (pnamelen > 0) ? pname[pnamelen-1] : 0;
*holder = '\0';
/* Quietly truncates on buffer overflow. Should be an error. */
if (pnamelen + strlen(fname) + 10 > (unsigned int)holderlen) {
*holder = '\0';
return;
}
if (pnamelen == 0) {
sprintf(holder, "%s.dll", fname);
} else if (c == ':' || c == '\\') {
sprintf(holder, "%s%s.dll", pname, fname);
} else {
sprintf(holder, "%s\\%s.dll", pname, fname);
dll_build_name(holder, holderlen, pname, fname);
}
}
......
/*
* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -33,30 +33,16 @@
#include <string.h>
#include <errno.h>
#define NPT_LIBNAME "npt.dll"
#define NPT_LIBNAME "npt"
#define NPT_INITIALIZE(pnpt,version,options) \
#define NPT_INITIALIZE(path,pnpt,version,options) \
{ \
HINSTANCE jvm; \
void *_handle; \
void *_sym; \
char buf[FILENAME_MAX+32]; \
char *lastSlash; \
\
if ( (pnpt) == NULL ) NPT_ERROR("NptEnv* is NULL"); \
_handle = NULL; \
*(pnpt) = NULL; \
buf[0] = 0; \
jvm = GetModuleHandle("jvm.dll"); \
if ( jvm == NULL ) NPT_ERROR("Cannot find jvm.dll"); \
GetModuleFileName(jvm, buf, FILENAME_MAX); \
lastSlash = strrchr(buf, '\\'); \
if ( lastSlash != NULL ) { \
*lastSlash = '\0'; \
(void)strcat(buf, "\\..\\"); \
(void)strcat(buf, NPT_LIBNAME); \
_handle = LoadLibrary(buf); \
} \
_handle = LoadLibrary(path); \
if ( _handle == NULL ) NPT_ERROR("Cannot open library"); \
_sym = GetProcAddress(_handle, "nptInitialize"); \
if ( _sym == NULL ) NPT_ERROR("Cannot find nptInitialize"); \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册