comparison agent/src/os/linux/LinuxDebuggerLocal.c @ 8670:96bd4772ec62

8008807: SA: jstack crash when target has mismatched bitness (Linux) Reviewed-by: rbackman, sla, poonam
author kevinw
date Wed, 27 Feb 2013 14:02:26 +0000
parents 9fae07c31641
children f2512d89ad0c
comparison
equal deleted inserted replaced
8667:1f9994892f89 8670:96bd4772ec62
1 /* 1 /*
2 * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
22 * 22 *
23 */ 23 */
24 24
25 #include <jni.h> 25 #include <jni.h>
26 #include "libproc.h" 26 #include "libproc.h"
27
28 #include <elf.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <fcntl.h>
32 #include <string.h>
33 #include <limits.h>
27 34
28 #if defined(x86_64) && !defined(amd64) 35 #if defined(x86_64) && !defined(amd64)
29 #define amd64 1 36 #define amd64 1
30 #endif 37 #endif
31 38
152 (*env)->CallBooleanMethod(env, loadObjectList, listAdd_ID, loadObject); 159 (*env)->CallBooleanMethod(env, loadObjectList, listAdd_ID, loadObject);
153 CHECK_EXCEPTION; 160 CHECK_EXCEPTION;
154 } 161 }
155 } 162 }
156 163
164
165 /*
166 * Verify that a named ELF binary file (core or executable) has the same
167 * bitness as ourselves.
168 * Throw an exception if there is a mismatch or other problem.
169 *
170 * If we proceed using a mismatched debugger/debuggee, the best to hope
171 * for is a missing symbol, the worst is a crash searching for debug symbols.
172 */
173 void verifyBitness(JNIEnv *env, const char *binaryName) {
174 int fd = open(binaryName, O_RDONLY);
175 if (fd < 0) {
176 THROW_NEW_DEBUGGER_EXCEPTION("cannot open binary file");
177 }
178 unsigned char elf_ident[EI_NIDENT];
179 int i = read(fd, &elf_ident, sizeof(elf_ident));
180 close(fd);
181
182 if (i < 0) {
183 THROW_NEW_DEBUGGER_EXCEPTION("cannot read binary file");
184 }
185 #ifndef _LP64
186 if (elf_ident[EI_CLASS] == ELFCLASS64) {
187 THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 64 bit, use 64-bit java for debugger");
188 }
189 #else
190 if (elf_ident[EI_CLASS] != ELFCLASS64) {
191 THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 32 bit, use 32 bit java for debugger");
192 }
193 #endif
194 }
195
196
157 /* 197 /*
158 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal 198 * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
159 * Method: attach0 199 * Method: attach0
160 * Signature: (I)V 200 * Signature: (I)V
161 */ 201 */
162 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__I 202 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__I
163 (JNIEnv *env, jobject this_obj, jint jpid) { 203 (JNIEnv *env, jobject this_obj, jint jpid) {
204
205 // For bitness checking, locate binary at /proc/jpid/exe
206 char buf[PATH_MAX];
207 snprintf((char *) &buf, PATH_MAX, "/proc/%d/exe", jpid);
208 verifyBitness(env, (char *) &buf);
209 CHECK_EXCEPTION;
164 210
165 struct ps_prochandle* ph; 211 struct ps_prochandle* ph;
166 if ( (ph = Pgrab(jpid)) == NULL) { 212 if ( (ph = Pgrab(jpid)) == NULL) {
167 THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process"); 213 THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
168 } 214 }
183 struct ps_prochandle* ph; 229 struct ps_prochandle* ph;
184 230
185 execName_cstr = (*env)->GetStringUTFChars(env, execName, &isCopy); 231 execName_cstr = (*env)->GetStringUTFChars(env, execName, &isCopy);
186 CHECK_EXCEPTION; 232 CHECK_EXCEPTION;
187 coreName_cstr = (*env)->GetStringUTFChars(env, coreName, &isCopy); 233 coreName_cstr = (*env)->GetStringUTFChars(env, coreName, &isCopy);
234 CHECK_EXCEPTION;
235
236 verifyBitness(env, execName_cstr);
188 CHECK_EXCEPTION; 237 CHECK_EXCEPTION;
189 238
190 if ( (ph = Pgrab_core(execName_cstr, coreName_cstr)) == NULL) { 239 if ( (ph = Pgrab_core(execName_cstr, coreName_cstr)) == NULL) {
191 (*env)->ReleaseStringUTFChars(env, execName, execName_cstr); 240 (*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
192 (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr); 241 (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);