* Removed all Id tags.
[cacao.git] / src / native / jvmti / cacaodbg.c
index d5d8ef7908f526ef8e5162e3b0d4f7e0269e73c5..f5753dfe6430f3732325bcf4dbe8d7c38b25fb67 100644 (file)
    Authors: Martin Platter
 
    Changes: Edwin Steiner
+            Samuel Vinson
 
 
-   $Id: cacao.c,v 3.165 2006/01/03 23:44:38 twisti Exp $
-
 */
 
 #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 <unistd.h>
 #include <signal.h>
 #include <stdlib.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <semaphore.h>
-#include <sys/msg.h>
-#include <linux/user.h>
 #include <assert.h>
-
-/* count the request for workingdatalock */
-static int workingdatanum = 0;
+#include <sys/wait.h>
 
 
-/* msgqsendevent ***************************************************************
+/* jvmti_get_all_threads ******************************************************
 
-   sends a ptrace request to the cacaodbgserver process through the message 
-   queue
+   Gets an array of threadobjects of all threads
 
 *******************************************************************************/
+jvmtiError jvmti_get_all_threads (jint * threads_count_ptr, 
+                                                                 threadobject*** threads_ptr) {
+    int i = 0, cnt = 8; 
+    threadobject *thread, **tthreads;
+       
+#if defined(ENABLE_THREADS)
+       tthreads = MNEW(threadobject*, (sizeof(threadobject*) * cnt));
 
-static void msgqsendevent(ptrace_request *pt, ptrace_reply** rcvbuf, int buflen) {
-       int size;
+       thread = mainthreadobj;
+    do {
+        if(thread->o.thread != NULL) {
+                       fflush(stderr); 
 
-       pt->mtype = MSGQPTRACESND;
+                  /* count and copy only live threads */
+                  if (i>=cnt) {
+                          MREALLOC(tthreads,threadobject*,cnt,cnt+8);
+                          cnt += 8;
+                  }
+                  tthreads[i] = thread;
+                  i++;
+               }
+               thread = thread->prev;
+
+               /* repeat until we got the pointer to the mainthread twice */
+       } while (mainthreadobj != thread);
 
-       fprintf(stderr,"msgqsendevent send new message (kind %d)\n",pt->kind);
-       if (-1 == msgsnd(msgqid, pt, sizeof(ptrace_request), 0))
-               perror("debugger process: msgqsendevent send error: ");
+       fflush(stderr); 
 
-       size = sizeof(ptrace_reply)+buflen;
-       *rcvbuf =(ptrace_reply*) heap_allocate(size,true,NULL);
+    *threads_count_ptr = i;
+       *threads_ptr = tthreads;
 
-       if (-1 == msgrcv(msgqid, *rcvbuf, size, MSGQPTRACERCV, 0))
-               perror("debugger process: msgqsendevent receive error: ");
-       fprintf(stderr,"msgqsendevent reply received(kind %d)\n",pt->kind);
+    return JVMTI_ERROR_NONE;
+#else
+       return JVMTI_ERROR_NOT_AVAILABLE;
+#endif
 }
 
 
-/* getworkingdatalock *********************************************************
+/* jvmti_get_current_thread ***************************************************
 
-   blocks until the workingdata lock has been obtained
+   Get jthread structure of current thread. 
 
 *******************************************************************************/
-
-void getworkingdatalock() {
-       workingdatanum++;
-       if (workingdatanum==1) threads_sem_wait(&workingdata_lock);
+jthread jvmti_get_current_thread() {
+       return (jthread)(threads_get_current_threadobject())->o.thread;
 }
 
-/* releaseworkingdatalock *********************************************************
 
-   release workingdata lock
 
-*******************************************************************************/
+/*  breakpointtable_creator ***************************************************
 
-void releaseworkingdatalock() {
-       workingdatanum--;
-       assert(workingdatanum>=0);
-       if (workingdatanum==0) sem_post(&workingdata_lock);
-}
-
-/* getchildproc ***************************************************************
-
-   Get data count number of bytes from address addr for child process address 
-   space. After a successfull call *ptr points to a newly created array 
-   containing the requested data.
+   helper function to enlarge the breakpoint table if needed
 
 *******************************************************************************/
 
-void getchildproc (char **ptr, void* addr, int count) {
-       ptrace_request pt;
-       ptrace_reply  *rcvbuf;
-       
-       stopdebuggee();
-
-       pt.kind = PTPEEKDATA;
-       pt.addr = addr;
-       pt.data = count;
-
-       msgqsendevent (&pt,&rcvbuf,count);
-       *ptr = rcvbuf->data;
-
-       contdebuggee(0);
+static void breakpointtable_creator() {
+       struct _brkpt* tmp;
+       struct brkpts *jvmtibrkpt;
+
+       jvmtibrkpt = &dbgcom->jvmtibrkpt;;
+       if (jvmtibrkpt->size == 0) {
+               jvmtibrkpt->brk = MNEW(struct _brkpt, 16);
+               memset(jvmtibrkpt->brk, 0, sizeof(struct _brkpt)*16);
+               jvmtibrkpt->size = 16;
+               jvmtibrkpt->num = BEGINUSERBRK;
+       } else {
+               jvmtibrkpt->size += 16;
+               tmp = jvmtibrkpt->brk;
+               jvmtibrkpt->brk = MNEW(struct _brkpt, jvmtibrkpt->size);
+               memset(jvmtibrkpt->brk, 0, sizeof(struct _brkpt)*(jvmtibrkpt->size));
+               memcpy((void*)jvmtibrkpt->brk,(void*)tmp,jvmtibrkpt->size);
+               MFREE(tmp,struct _brkpt,jvmtibrkpt->size-16);
+       }       
 }
 
-/* threadobject2jthread *******************************************************
 
-   Convert a cacao threadobject to jthread (java_lang_Thread)
+/* jvmti_set_system_breakpoint ************************************************
 
-*******************************************************************************/
-jthread threadobject2jthread(threadobject* thread) {
-       java_lang_Thread* t;
-       
-       stopdebuggee();
+   sets a system breakpoint in breakpoint table and calls set breakpoint
 
-       fprintf (stderr,"debugger: threadobject2jthread\n");
-       fflush(stderr); 
+*******************************************************************************/
 
-       getchildproc((char**)&t, thread->o.thread, sizeof(java_lang_Thread));
-       t->header.vftbl = class_java_lang_Thread->vftbl;
-       t->vmThread = thread;
+void jvmti_set_system_breakpoint(int sysbrk, bool mode) {      
+       struct brkpts *jvmtibrkpt;
 
-       fprintf (stderr,"debugger: threadobject2jthread done (t: %p)\n",t);
-       fflush(stderr); 
+       pthread_mutex_lock(&dbgcomlock);
+       jvmtibrkpt = &dbgcom->jvmtibrkpt;
 
-       contdebuggee(0);
+       assert (sysbrk < BEGINUSERBRK); 
+       if (jvmtibrkpt->size == jvmtibrkpt->num)
+               breakpointtable_creator();
 
-       return (jthread)t;
+       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; 
 }
 
-/* allthreads *****************************************************************
-
-   Gets an array of threadobjects of all threads
-
-*******************************************************************************/
-jvmtiError allthreads (jint * threads_count_ptr, threadobject ** threads_ptr) {
-    int i = 0, cnt = 8; 
-       char *data;
-    threadobject *thread, *tthreads;;
-       void **addr, *mainthread;
 
-       stopdebuggee();
+/* jvmti_add_breakpoint *******************************************************
 
-       fprintf (stderr,"debugger: allthreads: addr of mainthreadobj: %p sizeof(threadobject*) %d sizeof(long) %d\n",&mainthreadobj,sizeof(threadobject*),sizeof(long));
-       fflush(stderr); 
-
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       tthreads = MNEW(jthread, (sizeof(threadobject) * cnt));
+   adds a breakpoint to breakpoint table and calls set breakpoint
 
-       stopdebuggee();
-       /* mainthreadobj is in the same place in the child process memory because 
-          the child is a copy of this process */
-       getchildproc(&data, &mainthreadobj,sizeof(threadobject*));
-       addr = (void**) data;
-       mainthread = *addr;
+*******************************************************************************/
 
-    do {
-               getchildproc(&data, *addr, sizeof(threadobject));
-               thread = (threadobject*) data;
-               fprintf (stderr,"debugger: get all threads addr %X *addr %X thread->info.prev %p &data %p data %p\n",addr, *addr, &(thread->info.prev), &data, data);
+void jvmti_add_breakpoint(void* addr, jmethodID method, jlocation location) {
+       struct brkpts *jvmtibrkpt;
 
-        if(thread->o.thread != NULL) {
-                       fprintf (stderr,"debugger: get all threads: thread alive (i %d cnt %d tthreads %p)\n",i,cnt,tthreads);
-                       fflush(stderr); 
+       pthread_mutex_lock(&dbgcomlock);
+       jvmtibrkpt = &dbgcom->jvmtibrkpt;;
 
-                  /* count and copy only live threads */
-                  if (i>=cnt) {
-                          MREALLOC(tthreads,threadobject,cnt,cnt+8);
-                          cnt += 8;
-                  }
-                  memcpy(&tthreads[i],thread,sizeof(threadobject));
-                  fprintf(stderr,"allthreads - i %d  tthreads[i].o.thread %p\n",i,tthreads[i].o.thread);
-                  i++;
-               }
-               *addr = (void*)thread->info.prev;
+       if (jvmtibrkpt->size == jvmtibrkpt->num)
+               breakpointtable_creator();
 
-               /* repeat until we got the pointer to the mainthread twice */
-       } while (mainthread != *addr);
+       assert (jvmtibrkpt->size > jvmtibrkpt->num);
+       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;
 
-       fprintf (stderr,"debugger: get all threads: %d thread alive - going to copy\n",i);
-       fflush(stderr); 
+       /* todo: set breakpoint */
+/*     jvmtibrkpt.brk[jvmtibrkpt.num].orig = */
+       jvmtibrkpt->num++;
+       pthread_mutex_unlock(&dbgcomlock);
 
-    *threads_count_ptr = i;
-       
-    *threads_ptr = (threadobject*) heap_allocate(sizeof(threadobject) * i,true,NULL);
-       memcpy(*threads_ptr,tthreads,sizeof(threadobject)*i);
-       MFREE(tthreads,threadobject,cnt);
-       
-       fprintf (stderr,"debugger: get all threads: done\n");
-       fflush(stderr); 
+       fprintf (stderr,"add brk done\n");
+}
 
-       contdebuggee(0);
 
-    return JVMTI_ERROR_NONE;
-#else
-       return JVMTI_ERROR_NOT_AVAILABLE;
-#endif
-}
 
 
-/* getcurrentthread ***********************************************************
+/* jvmti_cacaodbgserver_quit **************************************************
 
-   Get jthread structure of current thread. 
+   quits cacaodbgserver if the last jvmti environment gets disposed
 
 *******************************************************************************/
-jthread getcurrentthread() {
-    /* get current thread through stacktrace. */
-       threadobject *threads;
-       threadobject *currthread=(threadobject*)0xffffffff; /* 32 bit max value */
-       jint tcnt;
-       int i;
-    struct user_regs_struct *regs;
-       ptrace_request pt;
-       ptrace_reply* rcvbuf;
-
-       assert (allthreads(&tcnt, &threads) == JVMTI_ERROR_NONE);
-       
-       pt.kind=PTGETREG;
-       msgqsendevent(&pt,&rcvbuf,sizeof(struct user_regs_struct));
-       regs = rcvbuf->data;
-       
-
-       /* ebp address of current thread has to have a smaller nummeric value then
-          the bottom of the stack whose address is in 
-          currentthread->info._stackframeinfo; and a stack can belong to only one 
-          thread.
-          exception: before mainthread has been started
-        */
-       
-       if (threads[0].info._stackframeinfo != NULL) { 
-               fprintf (stderr,"debugger: get all threads: done\n");
-               for (i=0;i<tcnt;i++) {
-                       if ((regs->ebp < (long)threads[i].info._stackframeinfo)
-                               && ((long)&threads[i]> (long)currthread))
-                               currthread = &threads[i];
-               }
-       } else {
-        /* if the mainthread has not been started yet return mainthread */
-               fprintf (stderr,"debugger: getcurrentthread mainthreadobj - threads[0].o.thread %p\n",threads[0].o.thread);
-               currthread = &threads[0];
+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;
        }
-
-       return (jthread)threadobject2jthread(currthread);
+       pthread_mutex_unlock(&dbgcomlock);
 }
 
 
-/* contdebuggee ****************************************************************
 
-   Send request to continue debuggee process through the message queue to the 
-   cacaodbgserver process.
+/* jvmti_cacao_generic_breakpointhandler **************************************
+
+   convert cacao breakpoints in jvmti events and fire event
 
 *******************************************************************************/
 
-bool contdebuggee(int signal) {
-       ptrace_request pt;
-       ptrace_reply  *rcvbuf;
-
-       /* get lock for running state */ 
-       getworkingdatalock();
-       cdbgshmem->hastostop--; 
-
-       if ((!cdbgshmem->running)&&(cdbgshmem->hastostop==0)) {
-               /* release lock for running state */ 
-               releaseworkingdatalock();
-               pt.kind=PTCONT;
-               pt.data=signal;
-               msgqsendevent (&pt,&rcvbuf,sizeof(bool));
-               return  *((bool*)rcvbuf->data);
-       } else {
-               /* release lock for running state */ 
-               releaseworkingdatalock();
-               return false;
+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 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:
+               fprintf(stderr,"unhandled kind of cacao break %d\n",kindofbrk);
+               return;
        }
+       jvmti_fireEvent(&data);
 }
 
 
-/* stopdebuggee ***************************************************************
-
-   Helper function to stop debugge process. It only sends a signal to stop if 
-   the debuggee is not already stopped.
-
-*******************************************************************************/
-void stopdebuggee() {
-       /* get lock for running state */ 
-       getworkingdatalock();
-       cdbgshmem->hastostop++;
-       if (cdbgshmem->running) {
-               fprintf (stderr,"debugger process: going to stop debuggee\n");
-               fflush(stderr); 
-               /* release lock for running state */ 
-               releaseworkingdatalock();
-
-               if (kill (debuggee, SIGUSR2)==-1) {
-                       perror("debugger process: stopdebuggee kill error: ");
-               }
-       } else 
-               /* release lock for running state */ 
-               releaseworkingdatalock();
-}
-
 
-/* brktablecreator*************************************************************
+/* jvmti_cacao_debug_init ***************************************************************
 
-   helper function to enlarge the breakpoint table if needed
+   starts up a new cacaodbgserver process if needed
 
 *******************************************************************************/
 
-static void brktablecreator() {
-       struct _brkpt* tmp;
-       if (jvmtibrkpt.size == 0) {
-               jvmtibrkpt.brk = MNEW(struct _brkpt, 16);
-               memset(jvmtibrkpt.brk, 0, sizeof(struct _brkpt)*16);
-               jvmtibrkpt.size = 16;
-               jvmtibrkpt.num = BEGINUSERBRK;
+void jvmti_cacao_debug_init() {
+       pid_t dbgserver;        
+
+       /* start new cacaodbgserver if needed*/
+       pthread_mutex_lock(&dbgcomlock);
+       if (dbgcom == NULL) {
+               dbgcom = heap_allocate(sizeof(cacaodbgcommunication),true,NULL);                
+               dbgcom->running = 1;
+               jvmti = true;
+
+               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));
+
+               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 {
-               jvmtibrkpt.size += 16;
-               tmp = jvmtibrkpt.brk;
-               jvmtibrkpt.brk = MNEW(struct _brkpt, jvmtibrkpt.size);
-               memset(jvmtibrkpt.brk, 0, sizeof(struct _brkpt)*jvmtibrkpt.size);
-               memcpy((void*)jvmtibrkpt.brk,(void*)tmp,jvmtibrkpt.size);
-               MFREE(tmp,struct _brkpt,jvmtibrkpt.size-16);
-       }       
+               dbgcom->running++;
+               pthread_mutex_unlock(&dbgcomlock);
+       }
 }
 
 
-/* setsysbrkpt ****************************************************************
+/* jvmti_ClassFileLoadHook ****************************************************
 
-   sets a system breakpoint int breakpoint table and calls set breakpoint
+  prepares firing a new Class File Load Hook event
 
 *******************************************************************************/
 
-void setsysbrkpt(int sysbrk, void* addr) {
-       ptrace_request pt;
-       ptrace_reply  *rcvbuf;
+void jvmti_ClassFileLoadHook(utf* name, int class_data_len, 
+                                                        unsigned char* class_data, 
+                                                        java_objectheader* loader, 
+                                                        java_objectheader* protection_domain, 
+                                                        jint* new_class_data_len, 
+                                                        unsigned char** new_class_data) {
+       genericEventData d;
        
-       if (jvmtibrkpt.size == jvmtibrkpt.num)
-               brktablecreator();
-
-       assert (sysbrk < BEGINUSERBRK);
-       jvmtibrkpt.brk[sysbrk].addr = addr;
-
-       pt.kind = PTSETBRK;
-       pt.addr = addr;
-       msgqsendevent (&pt, &rcvbuf, sizeof(long));
-
-       jvmtibrkpt.brk[sysbrk].orig = ((long*)rcvbuf->data)[0];
-
-       fprintf (stderr,"setsysbrk %d %X  done\n",sysbrk, addr);
+       d.ev = JVMTI_EVENT_CLASS_FILE_LOAD_HOOK;
+       d.klass = NULL; /* class is not redefined */
+       d.object = loader;
+       d.name = (char*)MNEW(char,(utf_bytes(name)+1));
+       utf_sprint_convert_to_latin1(d.name, name);
+       d.protection_domain = protection_domain;
+       d.class_data = class_data;
+       d.jint1 = class_data_len;
+       d.new_class_data_len = new_class_data_len;
+       d.new_class_data = new_class_data;
+
+       jvmti_fireEvent(&d);
+       MFREE(d.name,char,utf_bytes(name)+1);
 }
 
 
-/* addbrkpt *******************************************************************
+/* jvmti_ClassFileLoadHook ****************************************************
 
-   adds a breakpoint to breakpoint table and calls set breakpoint
+  prepares firing a new Class Prepare or Load event
 
 *******************************************************************************/
 
-void addbrkpt(void* addr, jmethodID method, jlocation location) {
-       ptrace_request pt;
-       ptrace_reply  *rcvbuf;
-
-       if (jvmtibrkpt.size == jvmtibrkpt.num)
-               brktablecreator();
+void jvmti_ClassLoadPrepare(bool prepared, classinfo *c) {
+       genericEventData d;
 
-       assert (jvmtibrkpt.size > jvmtibrkpt.num);
-       fprintf (stderr,"add brk add: %X\n",addr);
-       jvmtibrkpt.brk[jvmtibrkpt.num].addr = addr;
-       jvmtibrkpt.brk[jvmtibrkpt.num].method = method;
-       jvmtibrkpt.brk[jvmtibrkpt.num].location = location;
-
-       pt.kind = PTSETBRK;
-       pt.addr = addr;
-       msgqsendevent (&pt, &rcvbuf, sizeof(long));
-       
-       jvmtibrkpt.brk[jvmtibrkpt.num].orig = ((long*)rcvbuf->data)[0];
-       jvmtibrkpt.num++;
+       if (prepared) 
+               d.ev = JVMTI_EVENT_CLASS_PREPARE;
+       else 
+               d.ev = JVMTI_EVENT_CLASS_LOAD;
 
-       fprintf (stderr,"add brk done\n");
+       d.klass = c;
+       jvmti_fireEvent(&d);    
 }
 
 
-/* setup_jdwp_thread *****************************************************
+/* jvmti_MonitorContendedEntering *********************************************
 
-   Helper function to start JDWP threads
+  prepares firing a new Monitor Contended Enter or Entered event
 
 *******************************************************************************/
 
-static void setup_jdwp_thread(char* transport) {
-       java_objectheader *o;
-       methodinfo *m;
-       java_lang_String  *s;
-       classinfo *class;
+void jvmti_MonitorContendedEntering(bool entered, jobject obj) {
+       genericEventData d;
 
-       /* new gnu.classpath.jdwp.Jdwp() */
-       class = load_class_from_sysloader(
-            utf_new_char("gnu.classpath.jdwp.Jdwp"));
-       if (!class)
-               throw_main_exception_exit();
+       if (entered) 
+               d.ev = JVMTI_EVENT_MONITOR_CONTENDED_ENTERED;
+       else 
+               d.ev = JVMTI_EVENT_MONITOR_CONTENDED_ENTER;
 
-       o = builtin_new(class);
+       d.object = obj;
 
-       if (!o)
-               throw_main_exception_exit();
-       
-       m = class_resolveclassmethod(class,
-                                     utf_init, 
-                                     NULL,
-                                     class_java_lang_Object,
-                                     true);
-       if (!m)
-            throw_main_exception_exit();
-        
-       vm_call_method(m,o);
-        
-       /* configure(transport,NULL) */
-       m = class_resolveclassmethod(
-            class, utf_new_char("configure"), 
-            utf_new_char("(Ljava/lang/String;)V"),
-            class_java_lang_Object,
-            false);
-
-       s = javastring_new_char(&transport[1]);
-
-       vm_call_method(m,o,s);
-
-       if (!m)
-               throw_main_exception_exit();
-
-
-       /* _doInitialization */
-       m = class_resolveclassmethod(class,
-                                     utf_new_char("_doInitialization"), 
-                                     utf_new_char("()V"),
-                                     class,
-                                     false);
-       
-       if (!m)
-            throw_main_exception_exit();
-        
-       vm_call_method(m,o);
+       jvmti_fireEvent(&d);    
 }
 
-/* cacaodbglisten *************************************************************
+/* jvmti_MonitorWaiting ******************************************************
 
-   setup listener thread for JDWP
+  prepares firing a new Monitor Wait or Waited event
 
 *******************************************************************************/
 
-void cacaodbglisten(char* transport) {
-       basic_event ev;
-       genericEventData data;
-       int i;
-
-       fprintf(stderr, "jdwp/debugger process jdwp pid %d\n",getpid()); 
-    fflush (stderr); 
-
-    log_text("jdwp/debugger process - set up jdwp listening thread");
-
-    /* setup listening thread (JDWP) */
-    setup_jdwp_thread(transport);
-
-    log_text("jdwp/debugger process - continue debuggee");
-    /* start to be debugged program */
-       contdebuggee(0);
-
-       /* handle messages from cacaodbgserver */
-       while (true) {
-               if (-1 == msgrcv(msgqid,&ev,sizeof(basic_event),MSGQDEBUGGER,0))
-                       perror("debugger process: cacaodbglisten: ");
-               
-               switch (ev.signal) {
-               case SIGTRAP:
-                       /* search the breakpoint that has been triggered */
-                       i=0;
-                       while ((ev.ip!=jvmtibrkpt.brk[i].addr) && (i<jvmtibrkpt.num)) i++;
-
-                       fprintf(stderr,"cacaodbglisten SIGTRAP switch after while loop i %d\n",i);
-
-                       switch (i) {
-                       case HEREWEGOBRK:
-                               /* herewego trap */
-                               if (!suspend) {
-                                       fprintf(stderr,"cacaodbglisten suspend false -> continue debuggee\n");
-                                       contdebuggee(0);
-                               } else {
-                                       fprintf(stderr,"cacaodbglisten suspend true -> do no continue debuggee\n");
-                                       getworkingdatalock();
-                                       cdbgshmem->hastostop=1;
-                                       releaseworkingdatalock();       
-                               }
-                               set_jvmti_phase(JVMTI_PHASE_LIVE);
-                               break;
-                       case SETTHREADOBJECTBRK:
-                                /* setthreadobject */
-                               fprintf(stderr,"IP %X == setthreadobject\n",ev.ip);
-                               data.ev=JVMTI_EVENT_THREAD_START;
-                               fireEvent(&data);
-                               break;
-                       default:
-                               if ((i >= BEGINUSERBRK) && (i<jvmtibrkpt.num)) {
-                                       log_text("todo: user defined breakpoints are not handled yet");
-                               } else {
-                                       log_text("breakpoint not handled - continue anyway");
-                                       contdebuggee(0);
-                               }
-                       }
-                       break;
-               case SIGQUIT:
-                       log_text("debugger process SIGQUIT");
-                       data.ev=JVMTI_EVENT_VM_DEATH;
-                       fireEvent(&data);               
-                       break;
-               default:
-                       log_text("signal not handled");
-               }
-       }
-}
+void jvmti_MonitorWaiting(bool wait, jobject obj, jlong timeout) {
+       genericEventData d;
 
-/* ipcrm ***********************************************************************
+       if (wait) {
+               d.ev = JVMTI_EVENT_MONITOR_WAIT;
+               d.jlong = timeout;
+       } else {
+               d.ev = JVMTI_EVENT_MONITOR_WAITED;
+               d.b = timeout != 0;
+       }
 
-   removes messages queue 
+       d.object = obj;
 
-********************************************************************************/
-void ipcrm() {
-       struct msqid_ds msgbuf;
-       struct shmid_ds shmbuf;
-       msgctl(msgqid, IPC_RMID, &msgbuf);
-       shmctl(shmid, IPC_RMID, &shmbuf);
+       jvmti_fireEvent(&d);    
 }
 
+/* jvmti_ThreadStartEnd ********************************************************
 
-/* cacaodbgfork ****************************************************************
-
-   create debugger/jdwp and debuggee process. Returns true if this is the 
-   parent (debugger/jdwp) process
+  prepares firing a new Thread Start or End event
 
-********************************************************************************/
-
-bool cacaodbgfork() {
-       int waitproc;
+*******************************************************************************/
 
-       /* todo: remove shared memory and msg queue on exit */
-    /* create/initialize semaphores/shared memory/message queue */
-       sem_init(&workingdata_lock, 1, 1);
+void jvmti_ThreadStartEnd(jvmtiEvent ev) {
+       genericEventData d;
 
-       shmid = shmget(IPC_PRIVATE, sizeof(cacaodbgserver_data), IPC_CREAT | 0x180);
-       if ((cdbgshmem = (cacaodbgserver_data*)shmat(shmid, NULL, 0)) == -1) {
-               perror("cacaodbgfork: shared memory attach error: ");
-               exit(1);
-       }
-       cdbgshmem->running = false;
-       cdbgshmem->hastostop = 1;
+       d.ev = ev;
+       jvmti_fireEvent(&d);    
+}
 
-       if ((msgqid =  msgget(IPC_PRIVATE, IPC_CREAT | 0x180)) == -1) {
-               perror("cacaodbgfork: message queue get error");
-               exit(1);
-       }
-       ;
+/* jvmti_NativeMethodBind *****************************************************
 
+  prepares firing a new Native Method Bind event
 
-       /* with this function the following process structure is created:
-          
-          cacaodbgserver 
-           \_ debuggee (client/cacao vm)
-               \_ debugger (jdwp/cacao vm)
+*******************************************************************************/
 
-        */
+void jvmti_NativeMethodBind(jmethodID method, void* address, 
+                                                       void** new_address_ptr) {
+       genericEventData d;
 
-       debuggee = fork();
-       if (debuggee  == (-1)) {
-               log_text("debuggee fork error");
-               exit(1);
-       } else {
-               if (debuggee == 0) { 
-                       /* debuggee process - this is where the java client is running */
-                       
-                       /* allow helper process to trace us  */
-                       if (TRACEME != 0)  exit(1);
-                       
-                       fprintf(stderr, "debugee pid %d\n",getpid()); 
-                       fflush (stderr); 
-                                       
-                       /* give parent/debugger process control */
-                       kill(getpid(),SIGUSR2);
-                       
-                       log_text("debuggee: continue with normal startup");
-                       
-                       /* continue with normal startup */      
-                       return false;
-               } else {
-                       log_text("debugger: fork listening jdwp process");
-                       waitproc = fork();
-
-                       if (waitproc == (-1)) {
-                               log_text("waitprocess fork error");
-                               exit(1);
-                       } else {
-                               if (waitproc == 0) {
-                                       log_text("jdwp process - create new jvmti environment");
-                                       
-                                       remotedbgjvmtienv = new_jvmtienv();
-
-                                       log_text("jdwp process - init VMjdwp");
-           
-                                       if (!VMjdwpInit(remotedbgjvmtienv)) exit(1);
-                                       
-                                       return true;
-                               } else {
-                                       /* Debugger process (parent of debugge process) 
-                                          Here a wait-loop is execute and all the ptrace calls are
-                                          done from within this process. 
-                                          
-                                          This call will never return */
-                                       
-                                       cacaodbgserver();
-                                       fprintf(stderr,"cacaodbgserver returned - exit\n");
-                                       ipcrm();
-                                       exit(0);
-                               } 
-                       }
-               }
-       }
-       return true; /* make compiler happy */
+       d.ev = JVMTI_EVENT_NATIVE_METHOD_BIND;
+       d.method = method;
+       d.address = address;
+       d.new_address_ptr = new_address_ptr;
+       
+       jvmti_fireEvent(&d);    
 }