#include "native/jvmti/jvmti.h"
#include "native/jvmti/cacaodbg.h"
-#include "native/jvmti/cacaodbgserver.h"
#include "native/jvmti/dbg.h"
#include "vm/vm.h"
#include "vm/loader.h"
#include <signal.h>
#include <stdlib.h>
#include <assert.h>
+#include <sys/wait.h>
-/* allthreads *****************************************************************
+/* jvmti_get_all_threads ******************************************************
Gets an array of threadobjects of all threads
*******************************************************************************/
-jvmtiError allthreads (jint * threads_count_ptr, threadobject*** threads_ptr) {
+jvmtiError jvmti_get_all_threads (jint * threads_count_ptr,
+ threadobject*** threads_ptr) {
int i = 0, cnt = 8;
threadobject *thread, **tthreads;
tthreads[i] = thread;
i++;
}
- thread = thread->info.prev;
+ thread = thread->prev;
/* repeat until we got the pointer to the mainthread twice */
} while (mainthreadobj != thread);
}
-/* getcurrentthread ***********************************************************
+/* jvmti_get_current_thread ***************************************************
Get jthread structure of current thread.
*******************************************************************************/
-jthread getcurrentthread() {
+jthread jvmti_get_current_thread() {
return (jthread)(threads_get_current_threadobject())->o.thread;
}
-/* brktablecreator*************************************************************
+/* breakpointtable_creator ***************************************************
helper function to enlarge the breakpoint table if needed
*******************************************************************************/
-static void brktablecreator() {
+static void breakpointtable_creator() {
struct _brkpt* tmp;
struct brkpts *jvmtibrkpt;
}
-/* setsysbrkpt ****************************************************************
+/* jvmti_set_system_breakpoint ************************************************
sets a system breakpoint in breakpoint table and calls set breakpoint
*******************************************************************************/
-void setsysbrkpt(int sysbrk, void* addr) {
+void jvmti_set_system_breakpoint(int sysbrk, bool mode) {
struct brkpts *jvmtibrkpt;
pthread_mutex_lock(&dbgcomlock);
- jvmtibrkpt = &dbgcom->jvmtibrkpt;;
+ jvmtibrkpt = &dbgcom->jvmtibrkpt;
+ assert (sysbrk < BEGINUSERBRK);
if (jvmtibrkpt->size == jvmtibrkpt->num)
- brktablecreator();
-
- assert (sysbrk < BEGINUSERBRK);
- jvmtibrkpt->brk[sysbrk].addr = addr;
-
-
- dbgcom->setbrkpt = true;
- dbgcom->brkaddr = addr;
- jvmtibrkpt->brk[sysbrk].orig = dbgcom->brkorig;
+ breakpointtable_creator();
+
+ if (mode) {
+ /* add breakpoint*/
+ if (jvmtibrkpt->brk[sysbrk].count > 0) {
+ jvmtibrkpt->brk[sysbrk].count++;
+ pthread_mutex_unlock(&dbgcomlock);
+ return;
+ }
+ dbgcom->addbrkpt = true;
+ dbgcom->brkaddr = jvmtibrkpt->brk[sysbrk].addr;
+ } else {
+ /* remove breakpoint*/
+ if ((jvmtibrkpt->brk[sysbrk].count == 1) ) {
+ jvmtibrkpt->brk[sysbrk].count--;
+ /* remove breakpoint */
+ dbgcom->addbrkpt = false;
+ dbgcom->brkaddr = jvmtibrkpt->brk[sysbrk].addr;
+ } else {
+ /* avoid negative counter values */
+ if (jvmtibrkpt->brk[sysbrk].count > 0) jvmtibrkpt->brk[sysbrk].count--;
+ pthread_mutex_unlock(&dbgcomlock);
+ return;
+ }
+ }
pthread_mutex_unlock(&dbgcomlock);
-
/* call cacaodbgserver */
+ __asm__ ("setsysbrkpt:");
TRAP;
-
- fprintf (stderr,"setsysbrk %d %X done\n",sysbrk, addr);
}
-/* addbrkpt *******************************************************************
+/* jvmti_add_breakpoint *******************************************************
adds a breakpoint to breakpoint table and calls set breakpoint
*******************************************************************************/
-void addbrkpt(void* addr, jmethodID method, jlocation location) {
+void jvmti_add_breakpoint(void* addr, jmethodID method, jlocation location) {
struct brkpts *jvmtibrkpt;
pthread_mutex_lock(&dbgcomlock);
jvmtibrkpt = &dbgcom->jvmtibrkpt;;
if (jvmtibrkpt->size == jvmtibrkpt->num)
- brktablecreator();
+ breakpointtable_creator();
assert (jvmtibrkpt->size > jvmtibrkpt->num);
- fprintf (stderr,"add brk add: %X\n",addr);
+ fprintf (stderr,"add brk add: %p\n",addr);
jvmtibrkpt->brk[jvmtibrkpt->num].addr = addr;
jvmtibrkpt->brk[jvmtibrkpt->num].method = method;
jvmtibrkpt->brk[jvmtibrkpt->num].location = location;
vm_call_method(m,o);
}
-/* cacaobreakpointhandler **********************************************************
- handles breakpoints. called by cacaodbgserver.
+/* jvmti_cacaodbgserver_quit **************************************************
+
+ quits cacaodbgserver if the last jvmti environment gets disposed
*******************************************************************************/
+void jvmti_cacaodbgserver_quit(){
+ pthread_mutex_lock(&dbgcomlock);
+ dbgcom->running--;
+ if (dbgcom->running == 0) {
+ __asm__ ("cacaodbgserver_quit:");
+ TRAP;
+ /* get cacaodbserver exit */
+ wait(NULL);
+ }
+ dbgcom = NULL;
+ pthread_mutex_unlock(&dbgcomlock);
+}
-void cacaobreakpointhandler() {
- basic_event ev;
- genericEventData data;
- int i;
-
- /* XXX to be continued :-) */
-
- fprintf(stderr,"breakpoint handler called\n");
- log_text(" - signal %d", ev.signal);
- switch (ev.signal) {
- case SIGTRAP:
- /* search the breakpoint that has been triggered */
- i=0;
- while ((ev.ip!=dbgcom->jvmtibrkpt.brk[i].addr) && (i<dbgcom->jvmtibrkpt.num)) i++;
-
- fprintf(stderr,"cacaodbglisten SIGTRAP switch after while loop i %d\n",i);
-
- switch (i) {
- case SETTHREADOBJECTBRK:
- /* threads_set_current_threadobject */
- fprintf(stderr,"IP %X == threads_set_current_threadobject\n",ev.ip);
- data.ev=JVMTI_EVENT_THREAD_START;
- fireEvent(&data);
- break;
- default:
- if ((i >= BEGINUSERBRK) && (i<dbgcom->jvmtibrkpt.num)) {
- log_text("todo: user defined breakpoints are not handled yet");
- } else
- log_text("breakpoint not handled - continue anyway");
- }
+
+
+/* jvmti_cacao_generic_breakpointhandler **************************************
+
+ convert cacao breakpoints in jvmti events and fire event
+
+*******************************************************************************/
+
+static void jvmti_cacao_generic_breakpointhandler(int kindofbrk){
+ genericEventData data;
+
+ switch (kindofbrk) {
+ case THREADSTARTBRK:
+ data.ev=JVMTI_EVENT_THREAD_START;
+ break;
+ case THREADENDBRK:
+ data.ev=JVMTI_EVENT_THREAD_END;
+ break;
+ case CLASSLOADBRK:
+ data.ev=JVMTI_EVENT_CLASS_LOAD;
+ break;
+ case CLASSPREPARERK:
+ data.ev=JVMTI_EVENT_CLASS_PREPARE;
break;
- case SIGQUIT:
- log_text("debugger process SIGQUIT");
- data.ev=JVMTI_EVENT_VM_DEATH;
- fireEvent(&data);
+ case CLASSFILELOADHOOKBRK:
+ data.ev=JVMTI_EVENT_CLASS_FILE_LOAD_HOOK;
+ break;
+ case COMPILEDMETHODLOADBRK:
+ data.ev=JVMTI_EVENT_COMPILED_METHOD_LOAD;
+ break;
+ case COMPILEDMETHODUNLOADBRK:
+ data.ev=JVMTI_EVENT_COMPILED_METHOD_UNLOAD;
break;
default:
- log_text("signal not handled");
+ fprintf(stderr,"unhandled kind of cacao break %d\n",kindofbrk);
+ return;
+ }
+ jvmti_fireEvent(&data);
+}
+
+
+
+/* jvmti_cacao_debug_init ***************************************************************
+
+ starts up a new cacaodbgserver process if needed
+
+*******************************************************************************/
+
+void jvmti_cacao_debug_init() {
+ pid_t dbgserver;
+ void* addr[2];
+
+ /* start new cacaodbgserver if needed*/
+ pthread_mutex_lock(&dbgcomlock);
+ if (dbgcom == NULL) {
+ dbgcom = heap_allocate(sizeof(cacaodbgcommunication),true,NULL);
+ dbgcom->running = 1;
+
+ breakpointtable_creator();
+ /* set addresses of hard coded TRAPs */
+ __asm__ ("movl $setsysbrkpt,%0;"
+ :"=m"(dbgcom->jvmtibrkpt.brk[SETSYSBRKPT].addr));
+ __asm__ ("movl $cacaodbgserver_quit,%0;"
+ :"=m"(dbgcom->jvmtibrkpt.brk[CACAODBGSERVERQUIT].addr));
+
+ jvmti_get_threads_breakpoints(addr);
+ dbgcom->jvmtibrkpt.brk[THREADSTARTBRK].addr = addr[0];
+ dbgcom->jvmtibrkpt.brk[THREADENDBRK].addr = addr[1];
+
+ dbgserver = fork();
+ if (dbgserver == (-1)) {
+ log_text("cacaodbgserver fork error");
+ exit(1);
+ } else {
+ if (dbgserver == 0) {
+ if (execlp("cacaodbgserver","cacaodbgserver",(char *) NULL) == -1) {
+ log_text("unable to execute cacaodbgserver");
+ exit(1);
+ }
+ }
+ }
+ pthread_mutex_unlock(&dbgcomlock);
+ /* let cacaodbgserver get ready */
+ sleep(1);
+ } else {
+ dbgcom->running++;
+ pthread_mutex_unlock(&dbgcomlock);
}
}
/* src/native/jvmti/cacaodbgserver.c - contains the cacaodbgserver process. This
- process controls the debuggee/cacao vm.
+ process controls the cacao vm through gdb
Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
Changes: Edwin Steiner
Samuel Vinson
- $Id: cacao.c,v 3.165 2006/01/03 23:44:38 twisti Exp $
+ $Id$
*/
#include <sys/wait.h>
#include <stdlib.h>
#include <stdio.h>
+#include <assert.h>
+#include <string.h>
-pid_t debuggee;
+FILE *gdbin, *gdbout; /* file descriptor for gdb pipes */
-/* getchildprocptrace *********************************************************
+struct _pending_brkpt {
+ int brknumber;
+ unsigned long threadid;
+ char* regs;
+};
- Get data count number of bytes from address addr for child process address
- space. Requested data is stored in the array pointed to by ptr.
+struct _pending_brkpt *pending_brkpts;
+int pending_brkpts_size;
-*******************************************************************************/
-static void getchildprocptrace (char *ptr, void* addr, int cnt) {
- long i, longcnt;
- long *p = (long*) ptr;
-
- longcnt = cnt/sizeof(long);
- for (i=0; i<longcnt; i++) {
- p[i]=GETMEM(debuggee,addr);
- if (p[i]==-1)
- {
- fprintf(stderr,"cacaodbgserver process: getchildprocptrace: %ld\n",i);
- perror("cacaodbgserver process: getchildprocptrace:");
- exit(1);
- }
- addr+=sizeof(long);
+
+static void closepipeend (int fd) {
+ if (close(fd) == -1) {
+ perror("unable to close pipe - ");
+ exit(1);
}
- i = GETMEM(debuggee,addr);
- memcpy(p+longcnt,&i,cnt%sizeof(long));
}
+/* startgdb *******************************************************************
-/* waitloop *******************************************************************
-
- waits and handles signals from debuggee/child process. Returns true if
- cacaodbgserver should exit.
+ starts a gdb session and creates two pipes connection gdb stdout/stdin to
+ gdbin/gdbout
*******************************************************************************/
-static bool waitloop(void* dbgcvm) {
- int status,retval,signal;
- void* ip;
- basic_event ev;
- cacaodbgcommunication vm;
- long data;
- struct _brkpt* brk;
+static void startgdb() {
+ char gdbargs[20];
+ int cacao2gdbpipe[2],gdb2cacaopipe[2];
- fprintf(stderr,"waitloop\n");
+ pipe(cacao2gdbpipe);
+ pipe(gdb2cacaopipe);
- retval = wait(&status);
+ snprintf(gdbargs,20,"--pid=%d",getppid());
- fprintf(stderr,"cacaodbgserver: waitloop we got something to do\n");
- if (retval == -1) {
- fprintf(stderr,"error in waitloop\n");
- perror("cacaodbgserver process: waitloop: ");
- return true;
- }
-
- if (retval != debuggee) {
- fprintf(stderr,"cacaodbgserver got signal from process other then debuggee/cacao vm\n");
- return false;
- }
-
- if (WIFSTOPPED(status)) {
- signal = WSTOPSIG(status);
-
- /* ignore SIGSEGV, SIGPWR, SIGBUS and SIGXCPU for now.
- todo: in future this signals could be used to detect Garbage
- Collection Start/Finish or NullPointerException Events */
- if ((signal == SIGSEGV) || (signal == SIGPWR) ||
- (signal == SIGBUS) || (signal == SIGXCPU)) {
- fprintf(stderr,"cacaodbgserver: ignore internal signal (%d)\n",signal);
- CONT(debuggee,signal);
- return false;
- }
-
- if (signal == SIGABRT) {
- fprintf(stderr,"cacaodbgserver: got SIGABRT from debugee - exit\n");
- return true;
- }
-
- ip = getip(debuggee);
- ip--; /* EIP has already been incremented */
- fprintf(stderr,"got signal: %d IP %X\n",signal,ip);
-
-
- ev.signal = signal;
- ev.ip = ip;
-
- /* handle breakpoint */
- getchildprocptrace((char*)&vm,dbgcvm,sizeof(cacaodbgcommunication));
+ switch(fork()) {
+ case -1:
+ fprintf(stderr,"cacaodbgserver: fork error\n");
+ exit(1);
+ case 0:
+ /* child */
+ closepipeend(gdb2cacaopipe[0]); /* read end */
+ closepipeend(cacao2gdbpipe[1]); /* write end */
- if (vm.setbrkpt) {
- /* set a breakpoint */
- setbrk(debuggee, vm.brkaddr, &vm.brkorig);
- CONT(debuggee,0);
- return false;
- }
+ /* connect stdin of gdb to cacao2gdbpipe */
+ dup2(cacao2gdbpipe[0],0);
+ /* connect stdout of gdb to gdb2cacaopipe */
+ dup2(gdb2cacaopipe[1],1);
- if (signal == SIGTRAP) {
- /* Breakpoint hit. Place original instruction and notify cacao vm to
- handle it */
- fprintf(stderr,"breakpoint hit\n");
+ if (execlp("gdb","gdb","--interpreter=mi" ,gdbargs,(char *) NULL)==-1){
+ fprintf(stderr,"cacaodbgserver: unable to start gdb\n");
+ exit(1);
}
+ default:
+ /* parent */
+ closepipeend(gdb2cacaopipe[1]); /* write end */
+ closepipeend(cacao2gdbpipe[0]); /* read end */
- return false;
+ gdbin = fdopen(gdb2cacaopipe[0],"r");
+ gdbout = fdopen(cacao2gdbpipe[1],"w");
}
-
- if (WIFEXITED(status)) {
- fprintf(stderr,"cacaodbgserver: debuggee/cacao vm exited.\n");
- return true;
+
+}
+
+
+#define SENDCMD(CMD) \
+ fprintf(gdbout,"%s",CMD); \
+ fflush(gdbout); \
+
+
+static void getgdboutput(char *inbuf,int buflen) {
+ int i=0;
+ inbuf[0]='\0';
+ do {
+ i += strlen(&inbuf[i]);
+ if (fgets(&inbuf[i],buflen-i,gdbin)==NULL) {
+ perror("cacaodbgserver: ");
+ exit(1);
+ }
+ } while(!(strncmp(OUTPUTEND,&inbuf[i],OUTPUTENDSIZE)==0));
+}
+
+
+/* dataevaluate ***************************************************************
+
+ evaluates expr returning long in gdb and returns the result
+
+*******************************************************************************/
+
+static unsigned long dataevaluate(char *expr) {
+ char *match, inbuf[160];
+
+ fprintf(gdbout,"-data-evaluate-expression %s\n",expr);
+ fflush(gdbout);
+
+ getgdboutput(inbuf,160);
+ if ((match=strstr(inbuf,DATAEVALUATE))==NULL) {
+ fprintf(stderr,"dataevaluate: no matching value\n");
+ return -1;
}
-
- if (WIFSIGNALED(status)) {
- fprintf(stderr,"cacaodbgserver: child terminated by signal %d\n",WTERMSIG(status));
+ return strtoll(&match[strlen(DATAEVALUATE)],NULL,16);
+}
+
+
+/* commonbreakpointhandler *****************************************************
+
+ called by gdb and hard coded breakpoint handler
+
+*******************************************************************************/
+
+static bool commonbreakpointhandler(char* sigbuf, int sigtrap) {
+ int numberofbreakpoints, i;
+ char tmp[INBUFLEN], *match;
+ unsigned long addr;
+
+ if ((match=strstr(sigbuf,SIGADDR))==NULL) {
+ fprintf(stderr,"commonbreakpointhandler: no matching address(%s)\n",
+ sigbuf);
return true;
}
-
- if (WIFCONTINUED(status)) {
- fprintf(stderr,"cacaodbgserver: continued\n");
+
+ addr = strtoll(&match[strlen(SIGADDR)],NULL,16);
+ if (sigtrap) addr--;
+
+
+ numberofbreakpoints = (int)dataevaluate("dbgcom->jvmtibrkpt.num");
+
+ i = -1;
+ do {
+ i++;
+ snprintf(tmp,INBUFLEN,"dbgcom->jvmtibrkpt.brk[%d].addr",i);
+ } while ((i<numberofbreakpoints) && (dataevaluate(tmp) != addr));
+
+ assert(i<numberofbreakpoints);
+
+ /* handle system breakpoints */
+ switch(i) {
+ case SETSYSBRKPT:
+ /* add a breakpoint */
+ fprintf(gdbout,"break *0x%lx\n",dataevaluate("dbgcom->brkaddr"));
+ fflush(gdbout);
+ getgdboutput(tmp,INBUFLEN);
+ break;
+ case CACAODBGSERVERQUIT:
+ SENDCMD("-gdb-exit\n");
return false;
+ default:
+ /* other breakpoints -> call jvmti_cacao_generic_breakpointhandler
+ in the cacao vm */
+ fprintf(gdbout,"call jvmti_cacao_generic_breakpointhandler(%d)\n",i);
+ fflush(gdbout);
+ getgdboutput(tmp,INBUFLEN);
}
-
-
- fprintf(stderr,"wait not handled(child not exited or stopped)\n");
- fprintf(stderr,"retval: %d status: %d\n",retval,status);
- CONT(debuggee,0);
- return false;
+ SENDCMD(CONTINUE);
+ getgdboutput(tmp,INBUFLEN);
+ return true;
}
-/* main (cacaodbgserver) ******************************************************
+/* controlloop ****************************************************************
- main function for cacaodbgserver process.
+ this function controls the gdb behaviour
*******************************************************************************/
-int main(int argc, char **argv) {
+static void controlloop() {
+ char inbuf[INBUFLEN], *match;
bool running = true;
- void *dbgcvm;
- int status;
-
- if (argc != 2) {
- fprintf(stderr,"cacaodbgserver: not enough arguments\n");
- fprintf(stderr, "cacaodbgserver cacaodbgcommunicationaddress\n");
-
- fprintf(stderr,"argc %d argv[0] %s\n",argc,argv[0]);
- exit(1);
- }
-
- dbgcvm=(cacaodbgcommunication*)strtol(argv[1],NULL,16);
- fprintf(stderr,"cacaodbgserver started pid %d ppid %d\n",getpid(), getppid());
+ pending_brkpts_size = 5;
+ pending_brkpts = malloc(sizeof(struct _pending_brkpt)*pending_brkpts_size);
- debuggee = getppid();
+ getgdboutput(inbuf,INBUFLEN); /* read gdb welcome message */
- if (TRACEATTACH(debuggee) == -1) perror("cacaodbgserver: ");
+ SENDCMD("handle SIGSEGV SIGPWR SIGXCPU SIGBUS noprint nostop\n");
+ getgdboutput(inbuf,INBUFLEN);
- fprintf(stderr,"cacaovm attached\n");
+ SENDCMD("print dbgcom\n");
+ getgdboutput(inbuf,INBUFLEN);
- if (wait(&status) == -1) {
- fprintf(stderr,"error initial wait\n");
- perror("cacaodbgserver: ");
- exit(1);
- }
+ SENDCMD(CONTINUE);
+ getgdboutput(inbuf,INBUFLEN);
- if (WIFSTOPPED(status))
- if (WSTOPSIG(status) == SIGSTOP)
- CONT(debuggee,0);
-
while(running) {
- running = !waitloop(dbgcvm);
+ getgdboutput(inbuf,INBUFLEN);
+
+ if ((match=strstr(inbuf,HCSIGTRAP))!=NULL) {
+ running = commonbreakpointhandler(match,1);
+ continue;
+ }
+
+ if ((match=strstr(inbuf,GDBBREAKPOINT))!=NULL) {
+ running = commonbreakpointhandler(match,0);
+ continue;
+ }
+
+ if (strstr(inbuf,EXITEDNORMALLY) != NULL) {
+ /* quit gdb */
+ SENDCMD ("-gdb-exit");
+ running = false;
+ continue;
+ }
+
+ if ((inbuf[0]!=LOGSTREAMOUTPUT) && (inbuf[0]!=CONSOLESTREAMOUTPUT))
+ fprintf(stderr,"gdbin not handled %s\n",inbuf);
}
- fprintf(stderr,"cacaodbgserver exit\n");
+
+ free(pending_brkpts);
+}
+
+/* main (cacaodbgserver) ******************************************************
+
+ main function for cacaodbgserver process.
+
+*******************************************************************************/
+
+int main(int argc, char **argv) {
+ startgdb();
+
+ controlloop();
+
+ return 0;
}
Samuel Vinson
- $Id: jvmti.c 4926 2006-05-15 21:32:09Z edwin $
+ $Id: jvmti.c 4944 2006-05-23 15:31:19Z motse $
*/
#include "vm/stringlocal.h"
#include "mm/memory.h"
#include "threads/native/threads.h"
+#include "threads/native/lock.h"
#include "vm/exceptions.h"
#include "native/include/java_util_Vector.h"
#include "native/include/java_io_PrintStream.h"
#include <pthread.h>
#endif
-#include "native/jvmti/stacktrace.h"
#include "dbg.h"
static jvmtiCapabilities JVMTI_Capabilities;
static lt_ptr unload;
-#define CHECK_PHASE_START if (!(0
+#define CHECK_PHASE_START if (!(false
#define CHECK_PHASE(chkphase) || (phase == chkphase)
#define CHECK_PHASE_END )) return JVMTI_ERROR_WRONG_PHASE
#define CHECK_CAPABILITY(env,CAP) if(((environment*)env)->capabilities.CAP == 0) \
in the data structure.
*******************************************************************************/
-static void execcallback(jvmtiEvent e, functionptr ec, genericEventData* data) {
+static void execute_callback(jvmtiEvent e, functionptr ec,
+ genericEventData* data) {
JNIEnv* jni_env = (JNIEnv*)_Jv_env;
fprintf(stderr,"execcallback called (event: %d)\n",e);
switch (e) {
case JVMTI_EVENT_VM_INIT:
+ if (phase != JVMTI_PHASE_LIVE) return;
case JVMTI_EVENT_THREAD_START:
case JVMTI_EVENT_THREAD_END:
- ((jvmtiEventThreadStart)ec) (data->jvmti_env, jni_env, data->thread);
+ if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
+ ((jvmtiEventThreadStart)ec)(data->jvmti_env,jni_env,data->thread);
break;
-
case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
+ if ((phase == JVMTI_PHASE_START) ||
+ (phase == JVMTI_PHASE_LIVE) ||
+ (phase == JVMTI_PHASE_PRIMORDIAL))
((jvmtiEventClassFileLoadHook)ec) (data->jvmti_env,
jni_env,
data->klass,
case JVMTI_EVENT_CLASS_PREPARE:
case JVMTI_EVENT_CLASS_LOAD:
- ((jvmtiEventClassLoad)ec) (data->jvmti_env, jni_env,
- data->thread, data->klass);
+ if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
+ ((jvmtiEventClassLoad)ec) (data->jvmti_env, jni_env,
+ data->thread, data->klass);
break;
case JVMTI_EVENT_VM_DEATH:
+ if (phase != JVMTI_PHASE_LIVE) return;
case JVMTI_EVENT_VM_START:
+ if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
((jvmtiEventVMStart)ec) (data->jvmti_env, jni_env);
break;
- case JVMTI_EVENT_EXCEPTION:
- ((jvmtiEventException)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->method,
- data->location,
- data->object,
- data->catch_method,
- data->catch_location);
- break;
-
- case JVMTI_EVENT_EXCEPTION_CATCH:
- ((jvmtiEventExceptionCatch)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->method,
- data->location,
- data->object);
- break;
-
- case JVMTI_EVENT_BREAKPOINT:
- case JVMTI_EVENT_SINGLE_STEP:
- ((jvmtiEventSingleStep)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->method,
- data->location);
- break;
-
- case JVMTI_EVENT_FRAME_POP:
- ((jvmtiEventFramePop)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->method,
- data->b);
- break;
-
- case JVMTI_EVENT_FIELD_ACCESS:
- ((jvmtiEventFieldAccess)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->method,
- data->location,
- data->klass,
- data->object,
- data->field);
- break;
-
- case JVMTI_EVENT_FIELD_MODIFICATION:
- ((jvmtiEventFieldModification)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->method,
- data->location,
- data->klass,
- data->object,
- data->field,
- data->signature_type,
- data->value);
- break;
-
- case JVMTI_EVENT_METHOD_ENTRY:
- ((jvmtiEventMethodEntry)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->method);
- break;
-
- case JVMTI_EVENT_METHOD_EXIT:
- ((jvmtiEventMethodExit)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->method,
- data->b,
- data->value);
- break;
-
case JVMTI_EVENT_NATIVE_METHOD_BIND:
- ((jvmtiEventNativeMethodBind)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->method,
- data->address,
- data->new_address_ptr);
- break;
-
- case JVMTI_EVENT_COMPILED_METHOD_LOAD:
- ((jvmtiEventCompiledMethodLoad)ec) (data->jvmti_env,
- data->method,
- data->jint1,
- data->address,
- data->jint2,
- data->map,
- data->compile_info);
- break;
-
- case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
- ((jvmtiEventCompiledMethodUnload)ec) (data->jvmti_env,
+ if ((phase == JVMTI_PHASE_START) ||
+ (phase == JVMTI_PHASE_LIVE) ||
+ (phase == JVMTI_PHASE_PRIMORDIAL))
+ ((jvmtiEventNativeMethodBind)ec) (data->jvmti_env, jni_env,
+ data->thread,
data->method,
- data->address);
+ data->address,
+ data->new_address_ptr);
break;
+
case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
- ((jvmtiEventDynamicCodeGenerated)ec) (data->jvmti_env,
- data->name,
- data->address,
- data->jint1);
+ if ((phase == JVMTI_PHASE_START) ||
+ (phase == JVMTI_PHASE_LIVE) ||
+ (phase == JVMTI_PHASE_PRIMORDIAL))
+ ((jvmtiEventDynamicCodeGenerated)ec) (data->jvmti_env,
+ data->name,
+ data->address,
+ data->jint1);
break;
- case JVMTI_EVENT_GARBAGE_COLLECTION_START:
- case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
- case JVMTI_EVENT_DATA_DUMP_REQUEST:
- ((jvmtiEventDataDumpRequest)ec) (data->jvmti_env);
- break;
- case JVMTI_EVENT_MONITOR_WAIT:
- ((jvmtiEventMonitorWait)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->object,
- data->jlong);
- break;
- case JVMTI_EVENT_MONITOR_WAITED:
- ((jvmtiEventMonitorWaited)ec) (data->jvmti_env, jni_env,
+ default:
+ if (phase != JVMTI_PHASE_LIVE) return;
+ switch (e) {
+ case JVMTI_EVENT_EXCEPTION:
+ ((jvmtiEventException)ec) (data->jvmti_env, jni_env,
data->thread,
+ data->method,
+ data->location,
data->object,
- data->b);
- break;
-
-
- case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
- case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
- ((jvmtiEventMonitorContendedEnter)ec) (data->jvmti_env, jni_env,
+ data->catch_method,
+ data->catch_location);
+ break;
+
+ case JVMTI_EVENT_EXCEPTION_CATCH:
+ ((jvmtiEventExceptionCatch)ec) (data->jvmti_env, jni_env,
+ data->thread,
+ data->method,
+ data->location,
+ data->object);
+ break;
+
+ case JVMTI_EVENT_BREAKPOINT:
+ case JVMTI_EVENT_SINGLE_STEP:
+ ((jvmtiEventSingleStep)ec) (data->jvmti_env, jni_env,
+ data->thread,
+ data->method,
+ data->location);
+ break;
+
+ case JVMTI_EVENT_FRAME_POP:
+ ((jvmtiEventFramePop)ec) (data->jvmti_env, jni_env,
+ data->thread,
+ data->method,
+ data->b);
+ break;
+
+
+ case JVMTI_EVENT_FIELD_ACCESS:
+ ((jvmtiEventFieldAccess)ec) (data->jvmti_env, jni_env,
+ data->thread,
+ data->method,
+ data->location,
+ data->klass,
+ data->object,
+ data->field);
+ break;
+
+ case JVMTI_EVENT_FIELD_MODIFICATION:
+
+ ((jvmtiEventFieldModification)ec) (data->jvmti_env, jni_env,
data->thread,
- data->object);
- break;
+ data->method,
+ data->location,
+ data->klass,
+ data->object,
+ data->field,
+ data->signature_type,
+ data->value);
+ break;
+
+ case JVMTI_EVENT_METHOD_ENTRY:
+ ((jvmtiEventMethodEntry)ec) (data->jvmti_env, jni_env,
+ data->thread,
+ data->method);
+ break;
+
+ case JVMTI_EVENT_METHOD_EXIT:
+ ((jvmtiEventMethodExit)ec) (data->jvmti_env, jni_env,
+ data->thread,
+ data->method,
+ data->b,
+ data->value);
+ break;
+
+ case JVMTI_EVENT_COMPILED_METHOD_LOAD:
+ ((jvmtiEventCompiledMethodLoad)ec) (data->jvmti_env,
+ data->method,
+ data->jint1,
+ data->address,
+ data->jint2,
+ data->map,
+ data->compile_info);
+ break;
+
+ case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
+ ((jvmtiEventCompiledMethodUnload)ec) (data->jvmti_env,
+ data->method,
+ data->address);
+ break;
+
+ case JVMTI_EVENT_GARBAGE_COLLECTION_START:
+ case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
+ case JVMTI_EVENT_DATA_DUMP_REQUEST:
+ ((jvmtiEventDataDumpRequest)ec) (data->jvmti_env);
+ break;
+
+ case JVMTI_EVENT_MONITOR_WAIT:
+ ((jvmtiEventMonitorWait)ec) (data->jvmti_env, jni_env,
+ data->thread,
+ data->object,
+ data->jlong);
+ break;
+
+ case JVMTI_EVENT_MONITOR_WAITED:
+ ((jvmtiEventMonitorWaited)ec) (data->jvmti_env, jni_env,
+ data->thread,
+ data->object,
+ data->b);
+ break;
- case JVMTI_EVENT_OBJECT_FREE:
- ((jvmtiEventObjectFree)ec) (data->jvmti_env, data->jlong);
- break;
- case JVMTI_EVENT_VM_OBJECT_ALLOC:
- ((jvmtiEventVMObjectAlloc)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->object,
- data->klass,
- data->jlong);
- break;
+ case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
+ case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
+ ((jvmtiEventMonitorContendedEnter)ec) (data->jvmti_env, jni_env,
+ data->thread,
+ data->object);
+ break;
+ case JVMTI_EVENT_OBJECT_FREE:
+ ((jvmtiEventObjectFree)ec) (data->jvmti_env, data->jlong);
+ break;
- default:
- log_text ("unknown event");
+ case JVMTI_EVENT_VM_OBJECT_ALLOC:
+ ((jvmtiEventVMObjectAlloc)ec) (data->jvmti_env, jni_env,
+ data->thread,
+ data->object,
+ data->klass,
+ data->jlong);
+ break;
+ default:
+ log_text ("unknown event");
+ }
+ break;
}
}
if (evm->mode == JVMTI_ENABLE) {
data->jvmti_env=&env->env;
ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
- execcallback(e, ec, data);
+ execute_callback(e, ec, data);
}
evm=evm->next;
}
} else { /* event enabled globally */
data->jvmti_env=&env->env;
ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
- execcallback(e, ec, data);
+ execute_callback(e, ec, data);
}
env=env->next;
missing EventData.
*******************************************************************************/
-void fireEvent(genericEventData* d) {
+void jvmti_fireEvent(genericEventData* d) {
jthread thread;
- /* todo : respect event order JVMTI-Spec:Multiple Co-located Events */
+ /* XXX todo : respect event order JVMTI-Spec:Multiple Co-located Events */
if (d->ev != JVMTI_EVENT_VM_START)
- thread = getcurrentthread();
+ thread = jvmti_get_current_thread();
else
thread = NULL;
- fprintf (stderr,"jvmti: fireEvent: %d\n",d->ev);
d->thread = thread;
dofireEvent(d->ev,d);
-
- /* if we need to send a VM_INIT event then also send a THREAD_START event */
- if (d->ev == JVMTI_EVENT_VM_INIT)
- dofireEvent(JVMTI_EVENT_THREAD_START,d);
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
jvmtiEvent event_type, jthread event_thread, ...)
{
CHECK_THREAD_IS_ALIVE(event_thread);
}
+
cacao_env = (environment*) env;
if ((mode != JVMTI_ENABLE) && (mode != JVMTI_DISABLE))
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
- switch (event_type) { /* check capability */
+ switch (event_type) { /* check capability and set system breakpoint */
case JVMTI_EVENT_EXCEPTION:
case JVMTI_EVENT_EXCEPTION_CATCH:
CHECK_CAPABILITY(env,can_generate_exception_events)
case JVMTI_EVENT_VM_OBJECT_ALLOC:
CHECK_CAPABILITY(env,can_generate_vm_object_alloc_events)
break;
+ case JVMTI_EVENT_THREAD_START:
+ jvmti_set_system_breakpoint(THREADSTARTBRK, mode);
+ break;
+ case JVMTI_EVENT_THREAD_END:
+ jvmti_set_system_breakpoint(THREADENDBRK, mode);
+ break;
+
default:
/* all other events are required */
if ((event_type < JVMTI_EVENT_START_ENUM) ||
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
jthread ** threads_ptr)
{
int i;
jvmtiError retval;
- log_text ("GetAllThreads called");
-
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
if ((threads_count_ptr == NULL) || (threads_ptr == NULL))
return JVMTI_ERROR_NULL_POINTER;
- retval=allthreads(threads_count_ptr, &threads);
+ retval=jvmti_get_all_threads(threads_count_ptr, &threads);
if (retval != JVMTI_ERROR_NONE) return retval;
*threads_ptr =
*******************************************************************************/
-jvmtiError
+static jvmtiError
SuspendThread (jvmtiEnv * env, jthread thread)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
ResumeThread (jvmtiEnv * env, jthread thread)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
StopThread (jvmtiEnv * env, jthread thread, jobject exception)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
InterruptThread (jvmtiEnv * env, jthread thread)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadInfo (jvmtiEnv * env, jthread t, jvmtiThreadInfo * info_ptr)
{
java_lang_Thread* th = (java_lang_Thread*)t;
- log_text("GetThreadInfo called");
-
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetOwnedMonitorInfo (jvmtiEnv * env, jthread thread,
jint * owned_monitor_count_ptr,
jobject ** owned_monitors_ptr)
java_objectheader **om;
lock_record_pool_t* lrp;
- log_text("GetOwnedMonitorInfo called - todo: fix object mapping");
+ log_text("GetOwnedMonitorInfo called");
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
while (lrp != NULL) {
for (j=0; j<lrp->header.size; j++) {
- if((lrp->lr[j].owner==(threadobject*)thread)&&
+/* if((lrp->lr[j].owner==(threadobject*)thread)&&
(!lrp->lr[j].waiting)) {
if (i>=size) {
MREALLOC(om,java_objectheader*,size,size*2);
}
om[i]=lrp->lr[j].o;
i++;
- }
+ }*/
}
lrp=lrp->header.next;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetCurrentContendedMonitor (jvmtiEnv * env, jthread thread,
jobject * monitor_ptr)
{
while ((lrp != NULL)&&(monitor==NULL)) {
for (j=0; j<lrp->header.size; j++) {
- if((lrp->lr[j].owner==(threadobject*)thread)&&(lrp->lr[j].waiting)) {
+/* if((lrp->lr[j].owner==(threadobject*)thread)&&(lrp->lr[j].waiting)) {
monitor=lrp->lr[j].o;
break;
- }
+ }*/
}
lrp=lrp->header.next;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
const void *arg, jint priority)
{
}
pthread_attr_setschedparam(&threadattr,&sp);
if (pthread_create(&((threadobject*)
- thread)->info.tid, &threadattr, &threadstartup, &rap)) {
+ thread)->tid, &threadattr, &threadstartup, &rap)) {
log_text("pthread_create failed");
assert(0);
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
jthreadGroup ** groups_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadGroupInfo (jvmtiEnv * env, jthreadGroup group,
jvmtiThreadGroupInfo * info_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadGroupChildren (jvmtiEnv * env, jthreadGroup group,
jint * thread_count_ptr, jthread ** threads_ptr,
jint * group_count_ptr, jthreadGroup ** groups_ptr)
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
{
stacktracebuffer* trace;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadState (jvmtiEnv * env, jthread thread, jint * thread_state_ptr)
{
java_lang_Thread* th = (java_lang_Thread*)thread;
#if defined(ENABLE_THREADS)
if((th->vmThread==NULL)&&(th->group==NULL)) { /* alive ? */
/* not alive */
- if (((threadobject*)th->vmThread)->info.tid == 0)
+ if (((threadobject*)th->vmThread)->tid == 0)
*thread_state_ptr = JVMTI_THREAD_STATE_TERMINATED;
} else {
/* alive */
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetFrameLocation (jvmtiEnv * env, jthread thread, jint depth,
jmethodID * method_ptr, jlocation * location_ptr)
{
if ((method_ptr == NULL)&&(location_ptr == NULL))
return JVMTI_ERROR_NULL_POINTER;
- sfi = ((threadobject*)thread)->info._stackframeinfo;
+ sfi = ((threadobject*)thread)->_stackframeinfo;
i = 0;
while ((sfi != NULL) && (i<depth)) {
*******************************************************************************/
-jvmtiError
+static jvmtiError
NotifyFramePop (jvmtiEnv * env, jthread thread, jint depth)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLocalObject (jvmtiEnv * env,
jthread thread, jint depth, jint slot, jobject * value_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLocalInt (jvmtiEnv * env,
jthread thread, jint depth, jint slot, jint * value_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jlong * value_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jfloat * value_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jdouble * value_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetLocalObject (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jobject value)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetLocalInt (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jint value)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jlong value)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jfloat value)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jdouble value)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
CreateRawMonitor (jvmtiEnv * env, const char *name,
jrawMonitorID * monitor_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
DestroyRawMonitor (jvmtiEnv * env, jrawMonitorID monitor)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
RawMonitorEnter (jvmtiEnv * env, jrawMonitorID monitor)
{
if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
*******************************************************************************/
-jvmtiError
+static jvmtiError
RawMonitorExit (jvmtiEnv * env, jrawMonitorID monitor)
{
if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
*******************************************************************************/
-jvmtiError
+static jvmtiError
RawMonitorWait (jvmtiEnv * env, jrawMonitorID monitor, jlong millis)
{
if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
*******************************************************************************/
-jvmtiError
+static jvmtiError
RawMonitorNotify (jvmtiEnv * env, jrawMonitorID monitor)
{
if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
*******************************************************************************/
-jvmtiError
+static jvmtiError
RawMonitorNotifyAll (jvmtiEnv * env, jrawMonitorID monitor)
{
if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
{
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
CHECK_CAPABILITY(env,can_generate_breakpoint_events)
-
+
/* addbrkpt */
log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
*******************************************************************************/
-jvmtiError
+static jvmtiError
ClearBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
ClearFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
ClearFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
Allocate (jvmtiEnv * env, jlong size, unsigned char **mem_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
Deallocate (jvmtiEnv * env, unsigned char *mem)
{
/* let Boehm GC do the job */
+ heap_free(mem);
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetClassSignature (jvmtiEnv * env, jclass klass, char **signature_ptr,
char **generic_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
{
classinfo *c;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
{
int size;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetClassModifiers (jvmtiEnv * env, jclass klass, jint * modifiers_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetClassMethods (jvmtiEnv * env, jclass klass, jint * method_count_ptr,
jmethodID ** methods_ptr)
{
- CHECK_PHASE_START
+ int i;
+
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
+
if ((klass == NULL)||(methods_ptr == NULL)||(method_count_ptr == NULL))
return JVMTI_ERROR_NULL_POINTER;
*method_count_ptr = (jint)((classinfo*)klass)->methodscount;
*methods_ptr = (jmethodID*)
heap_allocate(sizeof(jmethodID) * (*method_count_ptr),true,NULL);
-
- memcpy (*methods_ptr, ((classinfo*)klass)->methods,
- sizeof(jmethodID) * (*method_count_ptr));
-
+
+ for (i=0; i<*method_count_ptr;i++)
+ (*methods_ptr)[i]=(jmethodID) &(((classinfo*)klass)->methods[i]);
+
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetClassFields (jvmtiEnv * env, jclass klass, jint * field_count_ptr,
jfieldID ** fields_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetImplementedInterfaces (jvmtiEnv * env, jclass klass,
jint * interface_count_ptr,
jclass ** interfaces_ptr)
*******************************************************************************/
-jvmtiError
+static jvmtiError
IsInterface (jvmtiEnv * env, jclass klass, jboolean * is_interface_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
IsArrayClass (jvmtiEnv * env, jclass klass, jboolean * is_array_class_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetClassLoader (jvmtiEnv * env, jclass klass, jobject * classloader_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetObjectHashCode (jvmtiEnv * env, jobject object, jint * hash_code_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetObjectMonitorUsage (jvmtiEnv * env, jobject object,
jvmtiMonitorUsage * info_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
char **name_ptr, char **signature_ptr, char **generic_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
jclass * declaring_class_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
jint * modifiers_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
IsFieldSynthetic (jvmtiEnv * env, jclass klass, jfieldID field,
jboolean * is_synthetic_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
char **signature_ptr, char **generic_ptr)
{
if ((method == NULL) || (name_ptr == NULL) || (signature_ptr == NULL)
|| (generic_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
- if (m->name == NULL) return JVMTI_ERROR_INTERNAL;
-
*name_ptr = (char*)
heap_allocate(sizeof(char) * (m->name->blength),true,NULL);
utf_sprint_convert_to_latin1(*name_ptr, m->name);
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetMethodDeclaringClass (jvmtiEnv * env, jmethodID method,
jclass * declaring_class_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetMethodModifiers (jvmtiEnv * env, jmethodID method, jint * modifiers_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetArgumentsSize (jvmtiEnv * env, jmethodID method, jint * size_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLineNumberTable (jvmtiEnv * env, jmethodID method,
jint * entry_count_ptr, jvmtiLineNumberEntry ** table_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetMethodLocation (jvmtiEnv * env, jmethodID method,
jlocation * start_location_ptr,
jlocation * end_location_ptr)
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
jint * entry_count_ptr,
jvmtiLocalVariableEntry ** table_ptr)
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetBytecodes (jvmtiEnv * env, jmethodID method,
jint * bytecode_count_ptr, unsigned char **bytecodes_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
IsMethodNative (jvmtiEnv * env, jmethodID method, jboolean * is_native_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
IsMethodSynthetic (jvmtiEnv * env, jmethodID method,
jboolean * is_synthetic_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
{
int i,j;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetClassLoaderClasses (jvmtiEnv * env, jobject initiating_loader,
jint * class_count_ptr, jclass ** classes_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
PopFrame (jvmtiEnv * env, jthread thread)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
RedefineClasses (jvmtiEnv * env, jint class_count,
const jvmtiClassDefinition * class_definitions)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetVersionNumber (jvmtiEnv * env, jint * version_ptr)
{
if (version_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
- *version_ptr = JVMTI_VERSION_1_0;
+ *version_ptr = JVMTI_VERSION;
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
{
if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetSourceDebugExtension (jvmtiEnv * env, jclass klass,
char **source_debug_extension_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
IsMethodObsolete (jvmtiEnv * env, jmethodID method,
jboolean * is_obsolete_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
SuspendThreadList (jvmtiEnv * env, jint request_count,
const jthread * request_list, jvmtiError * results)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
ResumeThreadList (jvmtiEnv * env, jint request_count,
const jthread * request_list, jvmtiError * results)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
jint max_frame_count, jvmtiFrameInfo * frame_buffer,
jint * count_ptr)
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadListStackTraces (jvmtiEnv * env, jint thread_count,
const jthread * thread_list,
jint max_frame_count,
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
jvmtiStackInfo ** stack_info_ptr, jint * thread_count_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadLocalStorage (jvmtiEnv * env, jthread thread, void **data_ptr)
{
jvmtiThreadLocalStorage *tls;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetTag (jvmtiEnv * env, jobject object, jlong * tag_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetTag (jvmtiEnv * env, jobject object, jlong tag)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
ForceGarbageCollection (jvmtiEnv * env)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
IterateOverObjectsReachableFromObject (jvmtiEnv * env, jobject object,
jvmtiObjectReferenceCallback
object_reference_callback,
*******************************************************************************/
-jvmtiError
+static jvmtiError
IterateOverReachableObjects (jvmtiEnv * env, jvmtiHeapRootCallback
heap_root_callback,
jvmtiStackReferenceCallback
*******************************************************************************/
-jvmtiError
+static jvmtiError
IterateOverHeap (jvmtiEnv * env, jvmtiHeapObjectFilter object_filter,
jvmtiHeapObjectCallback heap_object_callback,
void *user_data)
*******************************************************************************/
-jvmtiError
+static jvmtiError
IterateOverInstancesOfClass (jvmtiEnv * env, jclass klass,
jvmtiHeapObjectFilter object_filter,
jvmtiHeapObjectCallback
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetObjectsWithTags (jvmtiEnv * env, jint tag_count, const jlong * tags,
jint * count_ptr, jobject ** object_result_ptr,
jlong ** tag_result_ptr)
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetJNIFunctionTable (jvmtiEnv * env,
const jniNativeInterface * function_table)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetJNIFunctionTable (jvmtiEnv * env, jniNativeInterface ** function_table)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetEventCallbacks (jvmtiEnv * env,
const jvmtiEventCallbacks * callbacks,
jint size_of_callbacks)
*******************************************************************************/
-jvmtiError
+static jvmtiError
GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
jvmtiExtensionFunctionInfo ** extensions)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
jvmtiExtensionEventInfo ** extensions)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetExtensionEventCallback (jvmtiEnv * env, jint extension_event_index,
jvmtiExtensionEvent callback)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
DisposeEnvironment (jvmtiEnv * env)
{
environment* cacao_env = (environment*)env;
cacao_env->tls = NULL;
- pthread_mutex_lock(&dbgcomlock);
- dbgcom->running--;
- if (dbgcom->running == 0) {
- TRAP;
- }
- pthread_mutex_unlock(&dbgcomlock);
+ jvmti_cacaodbgserver_quit();
/* let the GC do the rest */
return JVMTI_ERROR_NONE;
memcpy(*name_ptr, &str, sizeof(str)); \
break
-jvmtiError
+static jvmtiError
GetErrorName (jvmtiEnv * env, jvmtiError error, char **name_ptr)
{
if (name_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetJLocationFormat (jvmtiEnv * env, jvmtiJlocationFormat * format_ptr)
{
*format_ptr = JVMTI_JLOCATION_MACHINEPC;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
{
jmethodID mid, moremid;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
{
jmethodID mid;
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
{
jmethodID mid;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetPhase (jvmtiEnv * env, jvmtiPhase * phase_ptr)
{
if (phase_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetCurrentThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetCurrentThreadCpuTime (jvmtiEnv * env, jlong * nanos_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadCpuTime (jvmtiEnv * env, jthread thread, jlong * nanos_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
{
if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetTime (jvmtiEnv * env, jlong * nanos_ptr)
{
/* Note: this implementation copied directly from Japhar's, by Chris Toshok. */
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetPotentialCapabilities (jvmtiEnv * env,
jvmtiCapabilities * capabilities_ptr)
{
}
-#define CHECK_ADD_CAPABILITY(env,CAN) \
- if ((capabilities_ptr->CAN == 1) && \
- (JVMTI_Capabilities.CAN == 0)) \
- return JVMTI_ERROR_NOT_AVAILABLE; \
- env->capabilities.CAN = 1;
+#define CHECK_ADD_CAPABILITY(env,CAN) \
+ if (capabilities_ptr->CAN == 1) { \
+ if (JVMTI_Capabilities.CAN == 0) \
+ return JVMTI_ERROR_NOT_AVAILABLE; \
+ else \
+ env->capabilities.CAN = 1; \
+ }
/* AddCapabilities ************************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
AddCapabilities (jvmtiEnv * env, const jvmtiCapabilities * capabilities_ptr)
{
environment* cacao_env;
*******************************************************************************/
-jvmtiError
+static jvmtiError
RelinquishCapabilities (jvmtiEnv * env,
const jvmtiCapabilities * capabilities_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetAvailableProcessors (jvmtiEnv * env, jint * processor_count_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetEnvironmentLocalStorage (jvmtiEnv * env, void **data_ptr)
{
if ((env == NULL) || (data_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetEnvironmentLocalStorage (jvmtiEnv * env, const void *data)
{
if (env == NULL) return JVMTI_ERROR_NULL_POINTER;
*******************************************************************************/
-jvmtiError
+static jvmtiError
AddToBootstrapClassLoaderSearch (jvmtiEnv * env, const char *segment)
{
char* tmp_bcp;
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetVerboseFlag (jvmtiEnv * env, jvmtiVerboseFlag flag, jboolean value)
{
switch (flag) {
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetObjectSize (jvmtiEnv * env, jobject object, jlong * size_ptr)
{
CHECK_PHASE_START
};
-void set_jvmti_phase(jvmtiPhase p) {
+void jvmti_set_phase(jvmtiPhase p) {
genericEventData d;
fprintf (stderr,"set JVMTI phase %d\n",p);
case JVMTI_PHASE_START:
phase = p;
d.ev = JVMTI_EVENT_VM_START;
- /* this event is sent during start or live phase */
- log_text("set sysbrk in setthreadobj");
- setsysbrkpt(SETTHREADOBJECTBRK,(void*)&threads_set_current_threadobject);
break;
case JVMTI_PHASE_LIVE:
phase = p;
d.ev = JVMTI_EVENT_VM_INIT;
+ jvmti_fireEvent(&d);
+ /* thread start event for main thread */
+ d.ev = JVMTI_EVENT_THREAD_START;
break;
case JVMTI_PHASE_DEAD:
phase = p;
exit(1);
}
- fireEvent(&d);
+ jvmti_fireEvent(&d);
}
-jvmtiEnv* new_jvmtienv() {
+jvmtiEnv* jvmti_new_environment() {
environment* env;
- pid_t dbgserver;
- char* comaddr;
if (envs == NULL) {
envs = heap_allocate(sizeof(environment),true,NULL);
RelinquishCapabilities(&(env->env),&(env->capabilities));
env->EnvironmentLocalStorage = NULL;
env->tls = NULL;
-
- /* start new cacaodbgserver if needed*/
- pthread_mutex_lock(&dbgcomlock);
- if (dbgcom == NULL) {
- dbgcom = heap_allocate(sizeof(cacaodbgcommunication),true,NULL);
- dbgcom->running = 1;
- dbgcom->breakpointhandler = (void*)cacaobreakpointhandler;
- dbgserver = fork();
- if (dbgserver == (-1)) {
- log_text("cacaodbgserver fork error");
- exit(1);
- } else {
- if (dbgserver == 0) {
- comaddr = MNEW(char,11);
- snprintf(comaddr,11,"%p",dbgcom);
- if (execlp("cacaodbgserver","cacaodbgserver",comaddr,(char *) NULL) == -1) {
- log_text("unable to execute cacaodbgserver");
- exit(1);
- }
- }
- }
- } else {
- dbgcom->running++;
- }
- pthread_mutex_unlock(&dbgcomlock);
- sched_yield();
-
+
+ /* initialize cacao debugging facilities */
+ jvmti_cacao_debug_init();
return (jvmtiEnv*)env;
}
-void agentload(char* opt_arg, bool agentbypath, lt_dlhandle *handle, char **libname) {
+void jvmti_agentload(char* opt_arg, bool agentbypath, lt_dlhandle *handle, char **libname) {
lt_ptr onload;
char *arg;
int i=0,len;
if (retval != 0) exit (retval);
}
-void agentunload() {
+void jvmti_agentunload() {
if (unload != NULL) {
((JNIEXPORT void JNICALL (*) (JavaVM *vm)) unload)
((JavaVM*) &_Jv_JNIInvokeInterface);