/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#import <Foundation/Foundation.h>
#import <mach/mach.h>
#import <mach/mach_types.h>
#import <sys/sysctl.h>
#import <stdlib.h>
#import <sys/types.h>
#import <sys/ptrace.h>
}
}
}
}
#define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throw_new_debugger_exception(env, str); return value; }
(*env)->ThrowNew(env, (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException"), errMsg);
}
#else
#error "Unsupported architecture"
/*
* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
* Method: init0
* Signature: ()V
*/
}
/*
* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
* Method: lookupByName0
*/
{
if (debug) {
}
if (symbolicator != nil) {
}
if (debug) {
}
return address;
}
/*
* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
* Method: readBytesFromProcess0
* Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult;
*/
{
// must allocate storage instead of using former parameter buf
CHECK_EXCEPTION_(0);
unsigned long alignedAddress;
unsigned long alignedLength;
int *mapped;
long pageCount;
int i;
if (addr != alignedAddress) {
}
// Allocate storage for pages and flags.
// Try to read each of the pages.
for (i = 0; i < pageCount; i++) {
// assume all failures are unmapped pages
}
for (i = 0; i < pageCount; i++) {
if (i == 0) {
}
if (i == (pageCount - 1)) {
}
if (mapped[i]) {
}
}
return array;
}
/*
* Lookup the thread_t that corresponds to the given thread_id.
* The thread_id should be the result from calling thread_info() with THREAD_IDENTIFIER_INFO
* and reading the m_ident_info.thread_id returned.
* The returned thread_t is the mach send right to the kernel port for the corresponding thread.
*
* We cannot simply use the OSThread._thread_id field in the JVM. This is set to ::mach_thread_self()
* in the VM, but that thread port is not valid for a remote debugger to access the thread.
*/
if (debug) {
}
int i;
// get the list of all the send rights
if (result != KERN_SUCCESS) {
if (debug) {
}
return 0;
}
for(i = 0 ; i < thread_list_count; i++) {
// get the THREAD_IDENTIFIER_INFO for the send right
result = thread_info(thread_list[i], THREAD_IDENTIFIER_INFO, (thread_info_t) &m_ident_info, &count);
if (result != KERN_SUCCESS) {
if (debug) {
}
break;
}
// if this is the one we're looking for, return the send right
{
result_thread = thread_list[i];
break;
}
}
return result_thread;
}
/*
* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
* Method: getThreadIntegerRegisterSet0
* Signature: (J)[J
*/
{
if (debug)
printf("getThreadRegisterSet0 called\n");
unsigned int *r;
int i;
if (result != KERN_SUCCESS) {
if (debug)
return NULL;
}
// 40 32-bit registers on ppc, 16 on x86.
// Output order is the same as the order in the ppc_thread_state/i386_thread_state struct.
/* From AMD64ThreadContext.java
public static final int R15 = 0;
public static final int R14 = 1;
public static final int R13 = 2;
public static final int R12 = 3;
public static final int R11 = 4;
public static final int R10 = 5;
public static final int R9 = 6;
public static final int R8 = 7;
public static final int RDI = 8;
public static final int RSI = 9;
public static final int RBP = 10;
public static final int RBX = 11;
public static final int RDX = 12;
public static final int RCX = 13;
public static final int RAX = 14;
public static final int TRAPNO = 15;
public static final int ERR = 16;
public static final int RIP = 17;
public static final int CS = 18;
public static final int RFL = 19;
public static final int RSP = 20;
public static final int SS = 21;
public static final int FS = 22;
public static final int GS = 23;
public static final int ES = 24;
public static final int DS = 25;
public static final int FSBASE = 26;
public static final int GSBASE = 27;
*/
// 64 bit
#else
return registerArray;
}
/*
* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
* Method: translateTID0
* Signature: (I)I
*/
{
if (debug)
foreign_tid = tid;
&usable_tid, &type);
if (result != KERN_SUCCESS)
return -1;
if (debug)
return (jint) usable_tid;
}
// pass the signal to the process so we don't swallow it
int res;
return false;
}
return true;
}
// waits until the ATTACH has stopped the process
// by signal SIGSTOP
int ret;
int status;
while (true) {
// Wait for debuggee to stop.
if (ret >= 0) {
if (WIFSTOPPED(status)) {
// Any signal will stop the thread, make sure it is SIGSTOP. Otherwise SIGSTOP
// will still be pending and delivered when the process is DETACHED and the process
// will go to sleep.
// Debuggee stopped by SIGSTOP.
return true;
}
fprintf(stderr, "attach: Failed to correctly attach to VM. VM might HANG! [PTRACE_CONT failed, stopped by %d]\n", WSTOPSIG(status));
return false;
}
} else {
return false;
}
} else {
switch (errno) {
case EINTR:
continue;
break;
case ECHILD:
break;
case EINVAL:
break;
default:
break;
}
return false;
}
}
}
int res;
return false;
} else {
return ptrace_waitpid(pid);
}
}
/*
* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
* Method: attach0
* Signature: (I)V
*/
{
else
// get the task from the pid
if (result != KERN_SUCCESS) {
THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
}
// use ptrace to stop the process
// on os x, ptrace only needs to be called on the process, not the individual threads
if (ptrace_attach(jpid) != true) {
THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
}
if (jrsSymbolicator != nil) {
}
if (symbolicator != nil) {
}
if (symbolicator == nil) {
THROW_NEW_DEBUGGER_EXCEPTION("Can't attach symbolicator to the process");
}
}
/*
* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
* Method: detach0
* Signature: ()V
*/
{
// detach from the ptraced process causing it to resume execution
int pid;
if (k_res != KERN_SUCCESS) {
}
else {
if (res < 0) {
}
}
if (symbolicator != nil) {
}
}