* src/vm/vm.c (vm_create): make agentlib/agentpath work
authormotse <none@none>
Sat, 6 May 2006 18:29:55 +0000 (18:29 +0000)
committermotse <none@none>
Sat, 6 May 2006 18:29:55 +0000 (18:29 +0000)
* src/cacao/cacao.c (main): changes for jvmti/jdwp startup due to removal of jdwp process
* src/native/jni.c (JNI_CreateJavaVM): change order vm_create and initialization of _Jv_jvm due to jvmti agent support.
* src/native/vm/VMVirtualMachine.c: change name of jvmtienv and bugfixes of Samuel Vinson
* src/native/include/Makefile.am: add VMMethod.h
* src/native/jvmti/Makefile.am: removal of cacaodbgserver
* src/native/jvmti/jvmti.c: remove jdwp process and convert to thread
* src/native/jvmti/cacaodbg.h: idem
* src/native/jvmti/jvmti.h: idem
* src/native/jvmti/dbg.h: idem
* src/native/jvmti/cacaodbg.c: idem
* src/native/jvmti/dbg.c: idem
* src/native/jvmti/cacaodbgserver.c: change to a autonomous program and removal of jdwp thread.
* src/native/jvmti/VMjdwp.c (VMInit): different invocation due to removal of jdwp thread
* src/native/jvmti/VMjdwp.h: export jvmti environment and event callbacks.
* src/native/vm/VMMethod.c: initial/dummy implementation of VMMetod native method

16 files changed:
src/cacao/cacao.c
src/native/include/Makefile.am
src/native/jni.c
src/native/jvmti/Makefile.am
src/native/jvmti/VMjdwp.c
src/native/jvmti/VMjdwp.h [new file with mode: 0644]
src/native/jvmti/cacaodbg.c
src/native/jvmti/cacaodbg.h
src/native/jvmti/cacaodbgserver.c
src/native/jvmti/dbg.c
src/native/jvmti/dbg.h
src/native/jvmti/jvmti.c
src/native/jvmti/jvmti.h
src/native/vm/VMMethod.c [new file with mode: 0644]
src/native/vm/VMVirtualMachine.c
src/vm/vm.c

index 388d9e8660380b729b1d808601aa925f3e40c65e..4c5fb2cc014ca32d64404b7de6cefe3f7195cac8 100644 (file)
@@ -31,7 +31,7 @@
             Philipp Tomsich
             Christian Thalinger
 
-   $Id: cacao.c 4879 2006-05-05 17:34:49Z edwin $
+   $Id: cacao.c 4892 2006-05-06 18:29:55Z motse $
 
 */
 
@@ -50,6 +50,7 @@
 #if defined(ENABLE_JVMTI)
 #include "native/jvmti/jvmti.h"
 #include "native/jvmti/cacaodbg.h"
+
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
 #include <pthread.h>
 #endif
@@ -201,7 +202,7 @@ int main(int argc, char **argv)
 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
        stackbottom = &dummy;
 #endif
-       
+
        if (atexit(vm_exit_handler))
                throw_cacao_exception_exit(string_java_lang_InternalError,
                                                                   "Unable to register exit_handler");
@@ -221,8 +222,8 @@ int main(int argc, char **argv)
        JNI_CreateJavaVM(&jvm, (void **) &_Jv_env, vm_args);
 
 #if defined(ENABLE_JVMTI)
-       if (dbgprocess && jvmti && jdwp) /* is this the parent/debugger process ? */
-               set_jvmti_phase(JVMTI_PHASE_START);
+       pthread_mutex_init(&dbgcomlock,NULL);
+       set_jvmti_phase(JVMTI_PHASE_START);
 #endif
 
        /* do we have a main class? */
@@ -313,20 +314,24 @@ int main(int argc, char **argv)
                /*class_showmethods(currentThread->group->header.vftbl->class); */
 
 #if defined(ENABLE_JVMTI)
-               /* if this is the parent process than start the jdwp listening */
-               if (jvmti || jdwp) {
-                       fprintf(stderr, "jdwp/debugger set herewego brkpt %p\n",&&herewego);
-                       setsysbrkpt(HEREWEGOBRK,&&herewego);
-                       if (dbgprocess && jdwp) cacaodbglisten(transport);
+               /* start the jdwp listening */
+               if (jdwp) {
+                       log_text("cacao vm - init VMjdwp");
+                       if (!VMjdwpInit()) exit(1);
+                       setup_jdwp_thread(transport);
+                       if (!suspend) {
+                               fprintf(stderr,"suspend false -> continue debuggee\n");
+                       } else {
+                               fprintf(stderr,"suspend true -> do no continue debuggee(todo)\n");
+                               /* XXX todo*/
+                       }
                }
 
-               if (!dbgprocess) {
-                       fprintf(stderr,"debuggee: herewe go\n");
-                       fflush(stderr);
-               }
-               /* here we go... */
-       herewego:
+               set_jvmti_phase(JVMTI_PHASE_LIVE);
+
+               log_text("debuggee: herewe go");
 #endif
+
                (void) vm_call_method(m, NULL, oa);
 
                /* exception occurred? */
index 41fe92fd59df7d9e0fc8952627c440c3e64bb4a7..209fbd56b03f4216e922ffb9e7bf9715dceb5bf1 100644 (file)
@@ -28,7 +28,7 @@
 ##
 ## Changes:
 ##
-## $Id: Makefile.am 4594 2006-03-14 16:40:32Z twisti $
+## $Id: Makefile.am 4892 2006-05-06 18:29:55Z motse $
 
 ## Process this file with automake to produce Makefile.in
 
@@ -75,6 +75,7 @@ GEN_HEADER_FILES = \
 GEN_JVMTI_HEADER_FILES = \
        java_nio_ByteBuffer.h \
        gnu_classpath_jdwp_VMFrame.h \
+       gnu_classpath_jdwp_VMMethod.h \
        gnu_classpath_jdwp_VMVirtualMachine.h \
        gnu_classpath_jdwp_event_EventRequest.h
 
index ad056fe88e7ea9c7c6907bdadd4efcd225b27b08..ef96ff5c248659e6b7bee9f571dca015302f0d74 100644 (file)
@@ -32,7 +32,7 @@
             Christian Thalinger
                        Edwin Steiner
 
-   $Id: jni.c 4874 2006-05-05 14:36:18Z edwin $
+   $Id: jni.c 4892 2006-05-06 18:29:55Z motse $
 
 */
 
@@ -5825,10 +5825,6 @@ jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
 
        _Jv_env = env;
 
-       /* actually create the JVM */
-
-       if (!vm_create(_vm_args))
-               return -1;
 
        /* create and fill a JavaVM structure */
 
@@ -5836,9 +5832,15 @@ jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
        jvm->functions = &_Jv_JNIInvokeInterface;
 
        /* XXX Set the global variable.  Maybe we should do that differently. */
-
+       /* XXX JVMTI Agents needs a JavaVM  */
        _Jv_jvm = jvm;
 
+
+       /* actually create the JVM */
+
+       if (!vm_create(_vm_args))
+               return -1;
+
        /* setup the local ref table (must be created after vm_create) */
 
        lrt = GCNEW(localref_table);
index b9ce4697a4942ba65e20b2239ac0db7e0c9cf385..c78b6adf0e70b952fe1edc6f095f417833e829ea 100644 (file)
@@ -28,7 +28,7 @@
 ##
 ## Changes:
 ##
-## $Id: Makefile.am 4661 2006-03-21 00:04:59Z motse $
+## $Id: Makefile.am 4892 2006-05-06 18:29:55Z motse $
 
 ## Process this file with automake to produce Makefile.in
 
@@ -40,14 +40,16 @@ libjvmti_la_SOURCES = \
        jvmti.c \
        jvmti.h \
        VMjdwp.c \
+       VMjdwp.h \
        dbg.h\
         dbg.c\
         cacaodbg.h \
-        cacaodbg.c \
-       cacaodbgserver.c \
-       cacaodbgserver.h
+        cacaodbg.c
 
 
+## seperate cacaodbgserver executable
+##     cacaodbgserver.c \
+##     cacaodbgserver.h \
 
 ## Local variables:
 ## mode: Makefile
index 34811dcf86d354403e9852eb6d6d296b16fce8d5..e96be458b35bc1d724447400e4a716382348c703 100644 (file)
    Changes:             
 
 
-   $Id: VMjdwp.c 4661 2006-03-21 00:04:59Z motse $
+   $Id: VMjdwp.c 4892 2006-05-06 18:29:55Z motse $
 
 */
 
 #include "native/jvmti/jvmti.h"
 #include "native/jvmti/cacaodbg.h"
+#include "native/jvmti/VMjdwp.h"
 #include "vm/loader.h"
 #include "vm/exceptions.h"
 #include "vm/jit/asmpart.h"
@@ -351,24 +352,27 @@ static void GarbageCollectionFinish (jvmtiEnv *jvmti_env){
 }
 
 
-bool VMjdwpInit(jvmtiEnv* env) {
+/* it would be more apropriate to call this function from gnu-cp jdwp */
+bool VMjdwpInit() {
        int end, i=0;
        jvmtiCapabilities cap;
        jvmtiError e;
 
+       log_text("cacao vm - create new jvmti environment");
+       jvmtienv = new_jvmtienv();
 
        /* set eventcallbacks */
        if (JVMTI_ERROR_NONE != 
-               (*env)->SetEventCallbacks(env,
+               (*jvmtienv)->SetEventCallbacks(jvmtienv,
                                                           &jvmti_jdwp_EventCallbacks,
                                                           sizeof(jvmti_jdwp_EventCallbacks))){
                log_text("unable to setup event callbacks");
                return false;
        }
        
-       e = (*env)->GetPotentialCapabilities(env, &cap);
+       e = (*jvmtienv)->GetPotentialCapabilities(jvmtienv, &cap);
        if (e == JVMTI_ERROR_NONE) {
-               e = (*env)->AddCapabilities(env, &cap);
+               e = (*jvmtienv)->AddCapabilities(jvmtienv, &cap);
        }
        if (e != JVMTI_ERROR_NONE) {
                log_text("error adding jvmti capabilities");
@@ -379,7 +383,7 @@ bool VMjdwpInit(jvmtiEnv* env) {
        for (i = 0; i < end; i++) {
                /* enable standard VM callbacks  */
                if (((void**)&jvmti_jdwp_EventCallbacks)[i] != NULL) {
-                       e = (*env)->SetEventNotificationMode(env,
+                       e = (*jvmtienv)->SetEventNotificationMode(jvmtienv,
                                                                                                JVMTI_ENABLE,
                                                                                                JVMTI_EVENT_START_ENUM+i,
                                                                                                NULL);
diff --git a/src/native/jvmti/VMjdwp.h b/src/native/jvmti/VMjdwp.h
new file mode 100644 (file)
index 0000000..86e5843
--- /dev/null
@@ -0,0 +1,44 @@
+/* src/native/vm/VMjdwp.c - jvmti->jdwp interface
+
+   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+   J. Wenninger, Institut f. Computersprachen - TU Wien
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Contact: cacao@cacaojvm.org
+
+   Author: Martin Platter
+
+   Changes:             
+
+
+   $Id: VMjdwp.c 4661 2006-03-21 00:04:59Z motse $
+
+*/
+
+#ifndef _VMJDWP_H
+#define _VMJDWP_H
+
+#include "native/jvmti/jvmti.h"
+
+jvmtiEnv* jvmtienv;
+jvmtiEventCallbacks jvmti_jdwp_EventCallbacks;
+
+#endif
index 04792739cad6b32ba46a887e59a548d8a4071009..bcd2c888edef35a9fb4c525f20398a65edf7ac59 100644 (file)
@@ -28,7 +28,7 @@
    Authors: Martin Platter
 
    Changes: Edwin Steiner
-
+            Samuel Vinson
 
    $Id: cacao.c,v 3.165 2006/01/03 23:44:38 twisti Exp $
 
 #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;
-
-
-/* msgqsendevent ***************************************************************
-
-   sends a ptrace request to the cacaodbgserver process through the message 
-   queue
-
-*******************************************************************************/
-
-static void msgqsendevent(ptrace_request *pt, ptrace_reply** rcvbuf, int buflen) {
-       int size;
-
-       pt->mtype = MSGQPTRACESND;
-
-       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: ");
-
-       size = sizeof(ptrace_reply)+buflen;
-       *rcvbuf =(ptrace_reply*) heap_allocate(size,true,NULL);
-
-       if (-1 == msgrcv(msgqid, *rcvbuf, size, MSGQPTRACERCV, 0))
-               perror("debugger process: msgqsendevent receive error: ");
-       fprintf(stderr,"msgqsendevent reply received(kind %d)\n",pt->kind);
-}
-
-
-/* getworkingdatalock *********************************************************
-
-   blocks until the workingdata lock has been obtained
-
-*******************************************************************************/
-
-void getworkingdatalock() {
-       workingdatanum++;
-       if (workingdatanum==1) threads_sem_wait(&workingdata_lock);
-}
-
-/* releaseworkingdatalock *********************************************************
-
-   release workingdata lock
-
-*******************************************************************************/
-
-void releaseworkingdatalock() {
-       workingdatanum--;
-       assert(workingdatanum>=0);
-       if (workingdatanum==0) threads_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.
-
-*******************************************************************************/
-
-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);
-}
-
-/* threadobject2jthread *******************************************************
-
-   Convert a cacao threadobject to jthread (java_lang_Thread)
-
-*******************************************************************************/
-jthread threadobject2jthread(threadobject* thread) {
-       java_lang_Thread* t;
-       
-       stopdebuggee();
-
-       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;
-
-       fprintf (stderr,"debugger: threadobject2jthread done (t: %p)\n",t);
-       fflush(stderr); 
-
-       contdebuggee(0);
-
-       return (jthread)t;
-}
 
 /* allthreads *****************************************************************
 
    Gets an array of threadobjects of all threads
 
 *******************************************************************************/
-jvmtiError allthreads (jint * threads_count_ptr, threadobject ** threads_ptr) {
+jvmtiError allthreads (jint * threads_count_ptr, threadobject*** threads_ptr) {
     int i = 0, cnt = 8; 
-       char *data;
-    threadobject *thread, *tthreads;;
-       void **addr, *mainthread;
-
-       stopdebuggee();
-
-       fprintf (stderr,"debugger: allthreads: addr of mainthreadobj: %p sizeof(threadobject*) %d sizeof(long) %d\n",&mainthreadobj,sizeof(threadobject*),sizeof(long));
-       fflush(stderr); 
-
+    threadobject *thread, **tthreads;
+       
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       tthreads = MNEW(jthread, (sizeof(threadobject) * cnt));
-
-       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;
+       tthreads = MNEW(threadobject*, (sizeof(threadobject*) * cnt));
 
+       thread = mainthreadobj;
     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);
-
         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); 
 
                   /* count and copy only live threads */
                   if (i>=cnt) {
-                          MREALLOC(tthreads,threadobject,cnt,cnt+8);
+                          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);
+                  tthreads[i] = thread;
                   i++;
                }
-               *addr = (void*)thread->info.prev;
+               thread = thread->info.prev;
 
                /* repeat until we got the pointer to the mainthread twice */
-       } while (mainthread != *addr);
+       } while (mainthreadobj != thread);
 
-       fprintf (stderr,"debugger: get all threads: %d thread alive - going to copy\n",i);
        fflush(stderr); 
 
     *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); 
-
-       contdebuggee(0);
+       *threads_ptr = tthreads;
 
     return JVMTI_ERROR_NONE;
 #else
@@ -235,100 +102,10 @@ jvmtiError allthreads (jint * threads_count_ptr, threadobject ** threads_ptr) {
 
 *******************************************************************************/
 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];
-       }
-
-       return (jthread)threadobject2jthread(currthread);
-}
-
-
-/* contdebuggee ****************************************************************
-
-   Send request to continue debuggee process through the message queue to the 
-   cacaodbgserver process.
-
-*******************************************************************************/
-
-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;
-       }
+       return (jthread)((threadobject*)thread_getself())->o.thread;
 }
 
 
-/* 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*************************************************************
 
@@ -338,43 +115,51 @@ void stopdebuggee() {
 
 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;
+       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);
+               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);
        }       
 }
 
 
 /* setsysbrkpt ****************************************************************
 
-   sets a system breakpoint int breakpoint table and calls set breakpoint
+   sets a system breakpoint in breakpoint table and calls set breakpoint
 
 *******************************************************************************/
 
-void setsysbrkpt(int sysbrk, void* addr) {
-       ptrace_request pt;
-       ptrace_reply  *rcvbuf;
-       
-       if (jvmtibrkpt.size == jvmtibrkpt.num)
+void setsysbrkpt(int sysbrk, void* addr) {     
+       struct brkpts *jvmtibrkpt;
+
+       pthread_mutex_lock(&dbgcomlock);
+       jvmtibrkpt = &dbgcom->jvmtibrkpt;;
+
+       if (jvmtibrkpt->size == jvmtibrkpt->num)
                brktablecreator();
 
        assert (sysbrk < BEGINUSERBRK);
-       jvmtibrkpt.brk[sysbrk].addr = addr;
+       jvmtibrkpt->brk[sysbrk].addr = addr;
+
 
-       pt.kind = PTSETBRK;
-       pt.addr = addr;
-       msgqsendevent (&pt, &rcvbuf, sizeof(long));
+       dbgcom->setbrkpt = true;
+       dbgcom->brkaddr = addr;
+       jvmtibrkpt->brk[sysbrk].orig = dbgcom->brkorig;
+       pthread_mutex_unlock(&dbgcomlock);
 
-       jvmtibrkpt.brk[sysbrk].orig = ((long*)rcvbuf->data)[0];
+       /* call cacaodbgserver */
+       TRAP; 
 
        fprintf (stderr,"setsysbrk %d %X  done\n",sysbrk, addr);
 }
@@ -387,24 +172,24 @@ void setsysbrkpt(int sysbrk, void* addr) {
 *******************************************************************************/
 
 void addbrkpt(void* addr, jmethodID method, jlocation location) {
-       ptrace_request pt;
-       ptrace_reply  *rcvbuf;
+       struct brkpts *jvmtibrkpt;
+
+       pthread_mutex_lock(&dbgcomlock);
+       jvmtibrkpt = &dbgcom->jvmtibrkpt;;
 
-       if (jvmtibrkpt.size == jvmtibrkpt.num)
+       if (jvmtibrkpt->size == jvmtibrkpt->num)
                brktablecreator();
 
-       assert (jvmtibrkpt.size > jvmtibrkpt.num);
+       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;
+       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++;
+       /* todo: set breakpoint */
+/*     jvmtibrkpt.brk[jvmtibrkpt.num].orig = */
+       jvmtibrkpt->num++;
+       pthread_mutex_unlock(&dbgcomlock);
 
        fprintf (stderr,"add brk done\n");
 }
@@ -416,7 +201,7 @@ void addbrkpt(void* addr, jmethodID method, jlocation location) {
 
 *******************************************************************************/
 
-static void setup_jdwp_thread(char* transport) {
+void setup_jdwp_thread(char* transport) {
        java_objectheader *o;
        methodinfo *m;
        java_lang_String  *s;
@@ -471,190 +256,53 @@ static void setup_jdwp_thread(char* transport) {
        vm_call_method(m,o);
 }
 
-/* cacaodbglisten *************************************************************
+/* cacaobreakpointhandler **********************************************************
 
-   setup listener thread for JDWP
+   handles breakpoints. called by cacaodbgserver.
 
 *******************************************************************************/
 
-void cacaodbglisten(char* transport) {
+void cacaobreakpointhandler() {
        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);
+       /* XXX to be continued :-) */
 
-       /* handle messages from cacaodbgserver */
-       while (true) {
-               if (-1 == msgrcv(msgqid,&ev,sizeof(basic_event),MSGQDEBUGGER,0))
-                       perror("debugger process: cacaodbglisten: ");
+       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++;
                
-               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);               
+               fprintf(stderr,"cacaodbglisten SIGTRAP switch after while loop i %d\n",i);
+               
+               switch (i) {
+               case SETTHREADOBJECTBRK:
+                       /* setthreadobject */
+                       fprintf(stderr,"IP %X == setthreadobject\n",ev.ip);
+                       data.ev=JVMTI_EVENT_THREAD_START;
+                       fireEvent(&data);
                        break;
                default:
-                       log_text("signal not handled");
+                       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");
                }
+               break;
+       case SIGQUIT:
+               log_text("debugger process SIGQUIT");
+               data.ev=JVMTI_EVENT_VM_DEATH;
+               fireEvent(&data);               
+               break;
+       default:
+               log_text("signal not handled");
        }
 }
 
-/* ipcrm ***********************************************************************
-
-   removes messages queue 
-
-********************************************************************************/
-void ipcrm() {
-       struct msqid_ds msgbuf;
-       struct shmid_ds shmbuf;
-       msgctl(msgqid, IPC_RMID, &msgbuf);
-       shmctl(shmid, IPC_RMID, &shmbuf);
-}
-
-
-/* cacaodbgfork ****************************************************************
-
-   create debugger/jdwp and debuggee process. Returns true if this is the 
-   parent (debugger/jdwp) process
-
-********************************************************************************/
-
-bool cacaodbgfork() {
-       int waitproc;
-
-       /* todo: remove shared memory and msg queue on exit */
-    /* create/initialize semaphores/shared memory/message queue */
-       threads_sem_init(&workingdata_lock, true, 1);
-
-       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;
-
-       if ((msgqid =  msgget(IPC_PRIVATE, IPC_CREAT | 0x180)) == -1) {
-               perror("cacaodbgfork: message queue get error");
-               exit(1);
-       }
-       ;
-
-
-       /* with this function the following process structure is created:
-          
-          cacaodbgserver 
-           \_ debuggee (client/cacao vm)
-               \_ debugger (jdwp/cacao vm)
-
-        */
-
-       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 */
-}
-
-
 
 /*
  * These are local overrides for various environment variables in Emacs.
index cf84fecb911d2374695dc614948a8c820d4a649c..b5d1deb5e9eccd6fabb3f7dcdd28ad63519afe3b 100644 (file)
 
 #include "threads/native/threads.h"
 #include "native/jvmti/jvmti.h"
+#include "native/include/java_lang_String.h"
+#include <ltdl.h>
+
+
 
-#define MSGQEVENT        1
-#define MSGQPTRACEREQ    2
-#define MSGQPTRACEANS    3
 
 typedef struct {
        jvmtiEvent ev;
@@ -71,6 +72,33 @@ typedef struct {
        jlong jlong;
 } genericEventData;
 
+
+struct _brkpt {
+    jmethodID method;
+    jlocation location;
+    void* addr; /* memory address          */
+    long orig;  /* original memory content */
+};
+
+
+struct brkpts {
+       struct _brkpt* brk;
+       int num;
+       int size;
+};
+
+
+typedef struct {
+       int running;
+       void* breakpointhandler;
+       bool setbrkpt;
+       void* brkaddr;
+       long brkorig;
+       struct brkpts jvmtibrkpt;
+} cacaodbgcommunication;
+
+cacaodbgcommunication *dbgcom;
+
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
 struct _jrawMonitorID {
     java_lang_String *name;
@@ -92,57 +120,32 @@ struct threadmap thmap;
 
 
 /* constants where system breakpoints are stored in the breakpoint table     */
-#define HEREWEGOBRK           0 /* used for suspend VM on startup            */
-#define SETTHREADOBJECTBRK    1 /* used for EVENT_THREAD_START               */
-#define BEGINUSERBRK          2 /* here is where the first user breakpoint is 
+#define SETTHREADOBJECTBRK    0 /* used for EVENT_THREAD_START               */
+#define BEGINUSERBRK          1 /* here is where the first user breakpoint is 
                                                                   stored                                    */
-struct _brkpt {
-    jmethodID method;
-    jlocation location;
-    void* addr;
-    long orig; /* original memory content */
-};
-
 
-struct brkpts {
-       struct _brkpt* brk;
-       int num;
-       int size;
-};
-
-struct brkpts jvmtibrkpt;
 
 bool jdwp;                  /* debugger via jdwp                              */
 bool jvmti;                 /* jvmti agent                                    */
-bool dbgprocess;            /* ture if debugger else debuggee process         */
-pid_t debuggee;             /* PID of debuggee                                */
 
 char *transport, *agentarg; /* arguments for jdwp transport and agent load    */
 bool suspend;               /* should the virtual machine suspend on startup? */
 
+extern pthread_mutex_t dbgcomlock;
 
-bool cacaodbgfork();
-void cacaodbglisten(char* transport);
+void setup_jdwp_thread(char* transport);
+void cacaobreakpointhandler();
 jvmtiEnv* new_jvmtienv();
 void set_jvmti_phase(jvmtiPhase p);
-bool contdebuggee(int signal);
-void stopdebuggee();
 void fireEvent(genericEventData* data);
-bool VMjdwpInit(jvmtiEnv *jvmti_env);
-jvmtiEnv* remotedbgjvmtienv;
-jvmtiEventCallbacks jvmti_jdwp_EventCallbacks;
-void agentload(char* opt_arg);
+bool VMjdwpInit();
+void agentload(char* opt_arg, bool agentbypath, lt_dlhandle  *handle, char **libname);
 void agentunload();
-
-void getchildproc (char **ptr, void* addr, int count);
 void addbrkpt(void* addr, jmethodID method, jlocation location);
 void setsysbrkpt(int sysbrk, void* addr);
-jthread threadobject2jthread(threadobject* thread);
-jvmtiError allthreads (jint * threads_count_ptr, threadobject ** threads_ptr);
+jvmtiError allthreads (jint * threads_count_ptr, threadobject *** threads_ptr);
 jthread getcurrentthread();
 
-void ipcrm();
-
 #endif
 
 /*
index 1a4dd345b127a3062393eb7134ec0984d894f015..51a520bc49c5f88f6c6ead919d972fc814e97b0e 100644 (file)
@@ -1,5 +1,5 @@
 /* src/native/jvmti/cacaodbgserver.c - contains the cacaodbgserver process. This
-                                       process controls the debuggee.
+                                       process controls the debuggee/cacao vm.
 
    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
@@ -28,7 +28,7 @@
    Authors: Martin Platter
 
    Changes: Edwin Steiner
-
+            Samuel Vinson
 
    $Id: cacao.c,v 3.165 2006/01/03 23:44:38 twisti Exp $
 
 #include <signal.h>
 #include <sys/wait.h>
 #include <stdlib.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <semaphore.h>
-#include <sys/msg.h>
-#include <linux/user.h>
+#include <stdio.h>
 
+pid_t debuggee;
 
 /* getchildprocptrace *********************************************************
 
 
 *******************************************************************************/
 static void getchildprocptrace (char *ptr, void* addr, int cnt) {
-       int i, longcnt;
+       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) 
-                       perror("cacaodbgserver process: getchildprocptrace: ");
+               if (p[i]==-1)
+               {
+                       fprintf(stderr,"cacaodbgserver process: getchildprocptrace: %ld\n",i);
+                       perror("cacaodbgserver process: getchildprocptrace:");
+                       exit(1);
+               }
                addr+=sizeof(long);
        }
-       longcnt = GETMEM(debuggee,addr);
-       memcpy(ptr,&longcnt,cnt%sizeof(long));
-}
-
-/* contchild ******************************************************************
-
-   Helper function to continue child process. 
-
-*******************************************************************************/
-static bool contchild(int signal) {
-       /* get lock for running state */ 
-       threads_sem_wait(&workingdata_lock);
-       fprintf(stderr,"cacaodbgserver: contchild called (hastostop: %d)\n",cdbgshmem->hastostop);
-       if(cdbgshmem->hastostop < 1) {
-               fprintf(stderr,"cacaodbgserver: going to continue child\n");
-               CONT(debuggee,signal);
-               cdbgshmem->hastostop = 0;
-               cdbgshmem->running=true;
-               /* release lock for running state */ 
-               threads_sem_post(&workingdata_lock);
-               return true;
-       } else {
-               threads_sem_post(&workingdata_lock);
-               return false;           
-       }
+       i = GETMEM(debuggee,addr);
+       memcpy(p+longcnt,&i,cnt%sizeof(long));
 }
 
-/* msgqsendevent *******************************************************************
-
-   sends an event notification to the jdwp/debugger process through the 
-   message queue
-
-*******************************************************************************/
-static void msgqsendevent(basic_event *ev) {
-       ev->mtype = MSGQDEBUGGER;
-       
-       if (-1 == msgsnd(msgqid, ev, sizeof(basic_event), 0)) {
-               perror("cacaodbgserver process: cacaodbglisten send error: ");
-               exit(1);
-       }
-}
 
 /* waitloop *******************************************************************
 
-   waits and handles signals from debuggee/child process
+   waits and handles signals from debuggee/child process. Returns true if 
+   cacaodbgserver should exit.
 
 *******************************************************************************/
 
-static void waitloop() {
+static bool waitloop(void* dbgcvm) {
     int status,retval,signal;
     void* ip;
        basic_event ev;
+       cacaodbgcommunication vm;
+       long data;
+       struct _brkpt* brk;
 
        fprintf(stderr,"waitloop\n");
-    fflush (stderr); 
-
-    while (true) {
-               retval = wait(&status);
 
-               fprintf(stderr,"cacaodbgserver: waitloop we got something to do\n");
-               if (retval == -1) {
-                       fprintf(stderr,"error in waitloop\n");
-                       perror("cacaodbgserver process: waitloop: ");
-                       exit(1);
-               }
+       retval = wait(&status);
 
-               if (retval != debuggee) {
-                       fprintf(stderr,"cacaodbgserver got signal from process other then debuggee\n");
-                       exit(1);
+       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 (WIFEXITED(status)) {
-                       /* generate event VMDeath */
-                       ev.signal = SIGQUIT;
-                       ev.ip = NULL;
-                       msgqsendevent(&ev);
-                       return;
+               if (signal == SIGABRT) {
+                       fprintf(stderr,"cacaodbgserver: got SIGABRT from debugee - exit\n");
+                       return true;
                }
                
-               if (WIFSTOPPED(status)) {
-                       signal = WSTOPSIG(status);
-
-                       /* ignore SIGSEGV, SIGPWR, SIGBUS and SIGXCPU for now.
-                          todo: in future this signals can 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);
-                               contchild(signal);
-                               continue;
-                       }
-
-                       if (signal == SIGABRT) {
-                               fprintf(stderr,"cacaodbgserver: got SIGABRT from debugee - exit\n");
-                               exit(1);
-                       }
-
-                       ip = getip(debuggee);
-                       ip--; /* EIP has already been incremented */
-                       fprintf(stderr,"got signal: %d IP %X\n",signal,ip);
-                       
-                       threads_sem_wait(&workingdata_lock);
-                       cdbgshmem->running = false;
-                       cdbgshmem->hastostop = 1;
-                       threads_sem_post(&workingdata_lock);
-
-                       if (signal==SIGUSR2) {
-                               fprintf(stderr,"SIGUSR2 - debuggee has stopped by jdwp process\n");
-                               return;
-                       }
+               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;
-                       msgqsendevent(&ev);
-                       return;
+               ev.signal = signal;
+               ev.ip = ip;
+               
+               /* handle breakpoint */
+               getchildprocptrace((char*)&vm,dbgcvm,sizeof(cacaodbgcommunication));
+               
+               if (vm.setbrkpt) {
+                       /* set a breakpoint */
+                       setbrk(debuggee, vm.brkaddr, &vm.brkorig);
+                       CONT(debuggee,0);
+                       return false;
                }
+
+               if (signal == SIGTRAP) {
+                       /* Breakpoint hit. Place original instruction and notify cacao vm to
+                          handle it */
+                       fprintf(stderr,"breakpoint hit\n");
+               }
+
+               return false;
+       }
        
-               fprintf(stderr,"wait not handled(child not exited or stopped)\n");
-               fprintf(stderr,"retval: %d status: %d\n",retval,status);
+       if (WIFEXITED(status)) {
+               fprintf(stderr,"cacaodbgserver: debuggee/cacao vm exited.\n");
+               return true;
+       }
+       
+       if (WIFSIGNALED(status)) {
+               fprintf(stderr,"cacaodbgserver: child terminated by signal %d\n",WTERMSIG(status));
+               return true;
        }
+       
+       if (WIFCONTINUED(status)) {
+               fprintf(stderr,"cacaodbgserver: continued\n");
+               return false;
+       }
+       
+       
+       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;
 }
 
-/* ptraceloop *****************************************************************
+/* main (cacaodbgserver) ******************************************************
 
-   this function handles the ptrace request from the jdwp/debugger process.
+   main function for cacaodbgserver process.
 
 *******************************************************************************/
 
-void ptraceloop() {
-       bool contdebuggee=false;
-       ptrace_request pt;
-       ptrace_reply *buffer;
-       int size;
-    struct user_regs_struct *regs;
-
-       fprintf(stderr,"ptraceloop\n");
-    fflush (stderr); 
-       while (!contdebuggee) {
-               if (-1 == msgrcv(msgqid, &pt, sizeof(ptrace_request), MSGQPTRACESND, 0))
-                       perror("cacaodbgserver process: cacaodbglisten receive error: ");
-
-               switch(pt.kind){
-               case PTCONT:
-                       /* continue debuggee process */
-                       size= sizeof(ptrace_reply);
-                       buffer =(ptrace_reply*) MNEW(char,size);
-
-                       contdebuggee = contchild(pt.data);
-
-                       buffer->mtype = MSGQPTRACERCV;
-                       buffer->successful=true;
-                       buffer->datasize=0;
-                       break;
-               case PTPEEKDATA:
-                       /* get memory content from the debuggee process */
-                       size= sizeof(ptrace_reply)+pt.data;
-                       buffer =(ptrace_reply*) MNEW(char,size);
-
-                       buffer->mtype = MSGQPTRACERCV;
-                       buffer->datasize = size-sizeof(ptrace_reply);
-
-                       fprintf(stderr,"getchildprocptrace: pid %d get %p - %p cnt: %d (buffer %p buffer->data %p)\n",
-                                       debuggee, pt.addr,pt.addr+pt.data, buffer->datasize,buffer, buffer->data);
-                       fflush(stderr);
-
-                       getchildprocptrace(buffer->data,pt.addr,buffer->datasize);
-                       break;
-               case PTSETBRK:
-                       size= sizeof(ptrace_reply)+sizeof(long);
-                       buffer =(ptrace_reply*) MNEW(char,size);
-
-                       /* set new breakpoint */
-                       buffer->mtype = MSGQPTRACERCV;
-                       buffer->successful=true;
-                       buffer->datasize=sizeof(long);
-                       
-                       setbrk(debuggee,pt.addr, (long*)(buffer->data));
-                       break;
-               case PTDELBRK:
-                       /* delete breakpoint */
-                       size= sizeof(ptrace_reply);
-                       buffer =(ptrace_reply*) MNEW(char,size);
-                       
-                       DISABLEBRK(debuggee,pt.ldata,pt.addr);
-                       
-                       buffer->mtype = MSGQPTRACERCV;
-                       buffer->successful=true;
-                       buffer->datasize=0;
-                       break;
-               case PTGETREG:
-                       /* get registers */
-                       size= sizeof(ptrace_reply)+sizeof(struct user_regs_struct);
-                       buffer =(ptrace_reply*) MNEW(char,size);
-                       regs=buffer->data;
-
-                       GETREGS(debuggee,*regs);
-                       
-                       buffer->mtype = MSGQPTRACERCV;
-                       buffer->successful=true;
-                       buffer->datasize=sizeof(struct user_regs_struct);
-                       break;
-               default:
-                       fprintf(stderr,"unkown ptrace request %d\n",pt.kind);
-                       exit(1);
-               }
+int main(int argc, char **argv) {
+       bool running = true;
+       void *dbgcvm;
+       int status;
+       
+       if (argc != 2) {
+               fprintf(stderr,"cacaodbgserver: not enough arguments\n");
+               fprintf(stderr, "cacaodbgserver cacaodbgcommunicationaddress\n");
 
-               if (-1 == msgsnd(msgqid, buffer, size, 0)) {
-                       perror("cacaodbgserver process: cacaodbglisten send error: ");
-                       exit(1);
-               }
-               MFREE(buffer,char,size);
+               fprintf(stderr,"argc %d argv[0] %s\n",argc,argv[0]);
+               exit(1);
        }
-}
 
-/* cacaodbgserver *************************************************************
+       dbgcvm=(cacaodbgcommunication*)strtol(argv[1],NULL,16);
 
-   waits for eventes from and issues ptrace calls to debuggee/child process
+       fprintf(stderr,"cacaodbgserver started pid %d ppid %d\n",getpid(), getppid());
 
-*******************************************************************************/
+       debuggee = getppid();
+
+       if (TRACEATTACH(debuggee) == -1) perror("cacaodbgserver: ");
 
-void cacaodbgserver() {
-       fprintf(stderr,"cacaodbgserver started\n");
-       fflush(stderr);
-       while(true) {
-               /* wait until debuggee process gets stopped 
-                  and inform debugger process */
-               waitloop();
-               /* give the debugger process the opportunity to issue ptrace calls */
-               ptraceloop();
-               /* ptraceloop returns after a PTRACE_CONT call has been issued     */
+       fprintf(stderr,"cacaovm attached\n");
+
+       if (wait(&status) == -1) {
+               fprintf(stderr,"error initial wait\n");
+               perror("cacaodbgserver: ");
+               exit(1);
+       }
+
+       if (WIFSTOPPED(status)) 
+               if (WSTOPSIG(status) == SIGSTOP)
+                       CONT(debuggee,0);
+       
+       while(running) {
+               running = !waitloop(dbgcvm);
        }
+       fprintf(stderr,"cacaodbgserver exit\n");
 }
 
 
index 4f669fa4c23171bed7d7d45c396b174f5b63cb07..7af016db2f9aae57f79cd093bf99b4c65bc854c0 100644 (file)
@@ -59,11 +59,12 @@ void setip(pid_t pid, void* ip) {
 
 void setbrk(pid_t pid, void* addr, long* orig) {
     long ins;
+
        *orig = GETMEM(pid,addr);
 
        ins = (*orig & ~0x000000FF) | TRAPINS; 
 
-       fprintf (stderr,"pid %d set brk at %p orig: %X new: %X\n",getpid(),addr,*orig,ins);
+       fprintf (stderr,"pid %d set brk at %p orig: %X new: %X\n",pid,addr,*orig,ins);
        if (ptrace(PTRACE_POKEDATA, pid, (caddr_t) addr, ins)==-1) 
                perror("setbrk error ");
 }
index 44370c39e953bce035e63cede5002bc50cafda09..52f63f295b29fa405a12ad5030c28a87a5d7c4f3 100644 (file)
@@ -29,7 +29,7 @@
    Changes:             
 
    
-   $Id: dbg.h 4661 2006-03-21 00:04:59Z motse $
+   $Id: dbg.h 4892 2006-05-06 18:29:55Z motse $
 
 */
 
@@ -42,7 +42,7 @@
 #include <sys/types.h>
 #include <sys/ptrace.h>
 
-#define TRACEME ptrace(PTRACE_TRACEME, 0, 0, 0)
+#define TRACEATTACH(pid) ptrace(PTRACE_ATTACH, pid, 0, 0)
 #define DETACH(pid,sig)  ptrace(PTRACE_DETACH, pid, 0, sig)
 #define TRAPINS 0xcc /* opcode for brk */
 #define TRAP asm("int3")
index b2afcadec2f6a67faa38b48fb75861454b6a4343..e4ff37fa7f15d3bd296736a8131b0e49e66e0981 100644 (file)
    Author: Martin Platter
 
    Changes: Edwin Steiner
+            Samuel Vinson
 
    
-   $Id: jvmti.c 4874 2006-05-05 14:36:18Z edwin $
+   $Id: jvmti.c 4892 2006-05-06 18:29:55Z motse $
 
 */
 
 #include "toolbox/logging.h"
 #include <stdlib.h>
 #include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/user.h>
-#include <signal.h>
 #include <ltdl.h>
+#include <unistd.h>
+#include <sched.h>
 
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
 #include "threads/native/threads.h"
 #include <pthread.h>
 #endif 
 
+#include "native/jvmti/stacktrace.h"
 #include "dbg.h"
 
+
 typedef struct _environment environment;
-environment *envs=NULL;
+static environment *envs=NULL;
+pthread_mutex_t dbgcomlock;
 
 extern const struct JNIInvokeInterface _Jv_JNIInvokeInterface;
 
@@ -99,12 +102,13 @@ struct _jvmtiEventModeLL {
 typedef struct _jvmtiThreadLocalStorage jvmtiThreadLocalStorage;
 struct _jvmtiThreadLocalStorage{
        jthread thread;
-       jvmtiThreadLocalStorage *next;
        void *data;
+       jvmtiThreadLocalStorage *next;
 };
 
 struct _environment {
     jvmtiEnv env;
+       environment *next;
     jvmtiEventCallbacks callbacks;
     /* table for enabled/disabled jvmtiEvents - first element contains global 
           behavior */
@@ -112,7 +116,6 @@ struct _environment {
     jvmtiCapabilities capabilities;
     void *EnvironmentLocalStorage;
        jvmtiThreadLocalStorage *tls;
-       environment *next;
 };
 
 static struct jvmtiEnv_struct JVMTI_EnvTable;
@@ -137,13 +140,8 @@ static lt_ptr unload;
 
 *******************************************************************************/
 static jvmtiError check_thread_is_alive(jthread t) {
-       char* data;
-       java_lang_Thread* th;
-       if(t==NULL) 
-               return JVMTI_ERROR_THREAD_NOT_ALIVE;
-       getchildproc(&data, t, sizeof(java_lang_Thread));
-       th = (java_lang_Thread*)data;
-       if(th->vmThread==NULL) 
+       if(t==NULL) return JVMTI_ERROR_THREAD_NOT_ALIVE;
+       if(((java_lang_Thread*) t)->vmThread==NULL) 
                return JVMTI_ERROR_THREAD_NOT_ALIVE;
        return JVMTI_ERROR_NONE;
 }
@@ -155,7 +153,7 @@ static jvmtiError check_thread_is_alive(jthread t) {
 
 *******************************************************************************/
 static void execcallback(jvmtiEvent e, functionptr ec, genericEventData* data) {
-       JNIEnv* jni_env = (JNIEnv*)&_Jv_JNINativeInterface;
+       JNIEnv* jni_env = (JNIEnv*)_Jv_env;
 
        fprintf(stderr,"execcallback called (event: %d)\n",e);
 
@@ -384,15 +382,14 @@ void fireEvent(genericEventData* d) {
     /* todo : respect event order JVMTI-Spec:Multiple Co-located Events */
 
        if (d->ev != JVMTI_EVENT_VM_START)
-               thread = (jthread)getcurrentthread();
+               thread = getcurrentthread();
        else
                thread = NULL;
 
-       fprintf (stderr,"debugger: fireEvent: %d\n",d->ev);
+       fprintf (stderr,"jvmti: fireEvent: %d\n",d->ev);
        d->thread = thread;
        dofireEvent(d->ev,d);
 
-       fprintf (stderr,"debugger: fireEvent 2\n");
        /* 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);
@@ -427,11 +424,6 @@ SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
        if ((mode != JVMTI_ENABLE) && (mode != JVMTI_DISABLE))
                return JVMTI_ERROR_ILLEGAL_ARGUMENT;
 
-       if ((event_type < JVMTI_EVENT_START_ENUM) ||
-               (event_type > JVMTI_EVENT_END_ENUM))
-               return JVMTI_ERROR_INVALID_EVENT_TYPE;
-       
-       
        switch (event_type) { /* check capability */
     case JVMTI_EVENT_EXCEPTION:
        case JVMTI_EVENT_EXCEPTION_CATCH:
@@ -483,6 +475,9 @@ SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
                break;
        default:
                /* all other events are required */
+               if ((event_type < JVMTI_EVENT_START_ENUM) ||
+                       (event_type > JVMTI_EVENT_END_ENUM))
+                       return JVMTI_ERROR_INVALID_EVENT_TYPE;          
                break;
        }
 
@@ -526,7 +521,7 @@ jvmtiError
 GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
               jthread ** threads_ptr)
 {
-       threadobject* threads;
+       threadobject** threads;
        int i;
        jvmtiError retval;
        
@@ -539,14 +534,14 @@ GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
     if ((threads_count_ptr == NULL) || (threads_ptr == NULL)) 
         return JVMTI_ERROR_NULL_POINTER;
 
-       retval=allthreads(threads_count_ptr,&threads);
+       retval=allthreads(threads_count_ptr, &threads);
        if (retval != JVMTI_ERROR_NONE) return retval;
 
        *threads_ptr = 
                heap_allocate(sizeof(jthread*)* (*threads_count_ptr),true,NULL);
 
-       for (i=0; i<*threads_count_ptr; i++) 
-               (*threads_ptr)[i] = threadobject2jthread(&threads[i]);
+       for (i=0; i<*threads_count_ptr; i++)
+               (*threads_ptr)[i] = threads[i]->o.thread;
  
     return JVMTI_ERROR_NONE;
 }
@@ -564,17 +559,10 @@ SuspendThread (jvmtiEnv * env, jthread thread)
        CHECK_PHASE_START
        CHECK_PHASE(JVMTI_PHASE_LIVE)
        CHECK_PHASE_END;
-    CHECK_CAPABILITY(env,can_suspend)
+    CHECK_CAPABILITY(env,can_suspend);
     
-/*    
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
-       suspend_thread((thread *) thread->thread);
-#endif
-
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       suspend_thread((threadobject*) thread);
-#endif
-*/
+       log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
+       return JVMTI_ERROR_NOT_AVAILABLE;
 
     return JVMTI_ERROR_NONE;
 }
@@ -591,17 +579,11 @@ ResumeThread (jvmtiEnv * env, jthread thread)
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-    CHECK_CAPABILITY(env,can_suspend)
+    CHECK_CAPABILITY(env,can_suspend);
 
-/*
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
-       resume_thread((thread *) this->thread);
-#endif
+       log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
+       return JVMTI_ERROR_NOT_AVAILABLE;
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       resume_thread((threadobject*) thread);
-#endif
-*/
     return JVMTI_ERROR_NONE;
 }
 
@@ -618,9 +600,11 @@ StopThread (jvmtiEnv * env, jthread thread, jobject exception)
        CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-    CHECK_CAPABILITY(env,can_signal_thread)
+    CHECK_CAPABILITY(env,can_signal_thread);
         
-  log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
+       log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
+       return JVMTI_ERROR_NOT_AVAILABLE;
+
     return JVMTI_ERROR_NONE;
 }
 
@@ -638,17 +622,15 @@ InterruptThread (jvmtiEnv * env, jthread thread)
     CHECK_PHASE_END;
     CHECK_CAPABILITY(env,can_signal_thread)
 
+       log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
+
+       return JVMTI_ERROR_NOT_AVAILABLE;
+
        if(!builtin_instanceof(thread,class_java_lang_Thread))
                return JVMTI_ERROR_INVALID_THREAD;
 
        CHECK_THREAD_IS_ALIVE(thread);        
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-/*     interruptThread((java_lang_VMThread*)thread);*/
-#else
-       return JVMTI_ERROR_NOT_AVAILABLE;
-#endif
-
     return JVMTI_ERROR_NONE;
 }
 
@@ -660,29 +642,20 @@ InterruptThread (jvmtiEnv * env, jthread thread)
 *******************************************************************************/
 
 jvmtiError
-GetThreadInfo (jvmtiEnv * env, jthread th, jvmtiThreadInfo * info_ptr)
+GetThreadInfo (jvmtiEnv * env, jthread t, jvmtiThreadInfo * info_ptr)
 {
-       int size;
-       char* data;
-       struct java_lang_Thread *t;
+       java_lang_Thread* th = (java_lang_Thread*)t;
 
        log_text("GetThreadInfo called");
 
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-
-       getchildproc(&data,th,sizeof(struct java_lang_Thread));
-       t = (java_lang_Thread*)data;
-       info_ptr->priority=(jint)t->priority;
-       info_ptr->is_daemon=(jboolean)t->daemon;
-       info_ptr->thread_group=(jthreadGroup)t->group;
-       info_ptr->context_class_loader=(jobject)t->contextClassLoader;
-       getchildproc(&data,t->name,sizeof(struct java_lang_String));
-       size = ((struct java_lang_String*)data)->count;
-       getchildproc(&(info_ptr->name),((struct java_lang_String*)data)->value,size);
-       info_ptr->name[size]='\0';
-
+       info_ptr->priority=(jint)th->priority;
+       info_ptr->is_daemon=(jboolean)th->daemon;
+       info_ptr->thread_group=(jthreadGroup)th->group;
+       info_ptr->context_class_loader=(jobject)th->contextClassLoader;
+       info_ptr->name= javastring_tochar((java_objectheader *)th->name);
 
     return JVMTI_ERROR_NONE;
 }
@@ -701,9 +674,8 @@ GetOwnedMonitorInfo (jvmtiEnv * env, jthread thread,
        int i,j,size=20;
        java_objectheader **om;
        lockRecordPool* lrp;
-       char *data;
 
-       log_text("GetOwnedMonitorInfo called");
+       log_text("GetOwnedMonitorInfo called - todo: fix object mapping");
 
        CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
@@ -722,12 +694,8 @@ GetOwnedMonitorInfo (jvmtiEnv * env, jthread thread,
 
        om=MNEW(java_objectheader*,size);
 
-       stopdebuggee();
-
-       /* global_pool is in the same place in the child process memory because the
-          the child is a copy of this process */
-       getchildproc(&data, &global_pool,sizeof(lockRecordPool*));
-       lrp=(lockRecordPool*)data;
+       pthread_mutex_lock(&pool_lock);
+       lrp=global_pool;
 
        while (lrp != NULL) {
                for (j=0; j<lrp->header.size; j++) {
@@ -821,7 +789,7 @@ typedef struct {
 
 static void *threadstartup(void *t) {
        runagentparam *rap = (runagentparam*)t;
-       rap->sf(rap->jvmti_env,&_Jv_JNINativeInterface,rap->arg);
+       rap->sf(rap->jvmti_env,(JNIEnv*)&_Jv_JNINativeInterface,rap->arg);
        return NULL;
 }
 
@@ -851,6 +819,9 @@ RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
                (priority > JVMTI_THREAD_MAX_PRIORITY)) 
                return JVMTI_ERROR_INVALID_PRIORITY;
 
+       /* XXX:  Threads started with with this function should not be visible to 
+          Java programming language queries but are included in JVM TI queries */
+
        rap.sf = proc;
        rap.arg = (void*)arg;
        rap.jvmti_env = env;
@@ -895,6 +866,8 @@ GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
 
+       log_text("GetTopThreadGroups called");
+
     if ((groups_ptr == NULL) || (group_count_ptr == NULL)) 
         return JVMTI_ERROR_NULL_POINTER;
 
@@ -915,7 +888,6 @@ GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
                        while((j<x)&&(tg[j]!=ttgp)) { /* unique ? */
                                j++;
                        }
-
                        if (j == x) {
                                if (x >= size){
                                        MREALLOC(tg,jthreadGroup*,size,size*2);
@@ -1030,11 +1002,15 @@ GetThreadGroupChildren (jvmtiEnv * env, jthreadGroup group,
    Has to take care of suspend/resume issuses
 
 *******************************************************************************/
-static jvmtiError getcacaostacktrace(char** trace, jthread thread) {
+static jvmtiError getcacaostacktrace(stacktracebuffer** trace, jthread thread) {
+       threadobject *t;
 
        log_text("getcacaostacktrace");
 
-       
+       t = (threadobject*)((java_lang_Thread*)thread)->vmThread;
+
+/*      XXX todo
+ *trace = stacktrace_create(t); */
 
     return JVMTI_ERROR_NONE;
 }
@@ -1042,6 +1018,7 @@ static jvmtiError getcacaostacktrace(char** trace, jthread thread) {
 
 /* GetFrameCount **************************************************************
 
+
    Get the number of frames in the specified thread's stack.
 
 *******************************************************************************/
@@ -1049,7 +1026,7 @@ static jvmtiError getcacaostacktrace(char** trace, jthread thread) {
 jvmtiError
 GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
 {
-       char* trace;
+       stacktracebuffer* trace;
        jvmtiError er;
 
        CHECK_PHASE_START
@@ -1066,7 +1043,7 @@ GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
        er = getcacaostacktrace(&trace, thread);
        if (er==JVMTI_ERROR_NONE) return er;
 
-/*     todo: *count_ptr = trace->size;*/
+       *count_ptr = trace->used;
 
     return JVMTI_ERROR_NONE;
 }
@@ -2137,8 +2114,7 @@ GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
         
-    /* todo: how do I find declaring class other then iterate over all fields in all classes ?*/
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       *declaring_class_ptr = (jclass) ((fieldinfo*)field)->class;
  
     return JVMTI_ERROR_NONE;
 }
@@ -2214,12 +2190,16 @@ GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
     if ((method == NULL) || (name_ptr == NULL) || (signature_ptr == NULL)
         || (generic_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
 
-    *name_ptr = (char*)heap_allocate(m->name->blength,true,NULL);
-    memcpy(*name_ptr, m->name->text, m->name->blength);
+       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);
+
+    *signature_ptr = (char*)
+               heap_allocate(sizeof(char) * (m->descriptor->blength),true,NULL);
+       utf_sprint_convert_to_latin1(*signature_ptr, m->descriptor);
 
-    *signature_ptr = (char*)heap_allocate(m->descriptor->blength,true,NULL);
-    memcpy(*signature_ptr, m->descriptor->text, m->descriptor->blength);
-    
     /* there is no generic signature attribute */
     *generic_ptr = NULL;
 
@@ -2399,6 +2379,7 @@ GetMethodLocation (jvmtiEnv * env, jmethodID method,
 
        /* XXX Don't know if that's the right way to deal with not-yet-
         * compiled methods. -Edwin */
+
        if (!m->code)
                return JVMTI_ERROR_NULL_POINTER;
        
@@ -2524,7 +2505,12 @@ GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
        classcache_name_entry *cne;
        classcache_class_entry *cce;
 
-       log_text ("GetLoadedClasses called");
+       log_text ("GetLoadedClasses called %d ", phase);
+
+
+       /* XXX todo */
+
+       *class_count_ptr = 0;
 
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
@@ -2535,10 +2521,9 @@ GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
 
        log_text ("GetLoadedClasses1");
 
-       stopdebuggee();
+/*
+       CLASSCACHE_LOCK();
        log_text ("GetLoadedClasses2");
-       /* hashtable_classcache is in the same place in the child process memory 
-          because the child is a copy of this process */
        getchildproc(&data, &hashtable_classcache, sizeof(hashtable));
        ht = (hashtable*) &data;
 
@@ -2549,23 +2534,24 @@ GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
        fflush(stderr);
 
        *class_count_ptr = ht->entries;
+       log_text ("GetLoadedClasses %d", *class_count_ptr);
        j=0;
-    /* look in every slot of the hashtable */
+     look in every slot of the hashtable 
        for (i=0; i<ht->size; i++) { 
                cne = ht->ptr[i];
 
-               while (cne != NULL) { /* iterate over hashlink */
+               while (cne != NULL) { iterate over hashlink 
                        getchildproc(&data, cne, sizeof(classcache_name_entry));
                        cne =(classcache_name_entry*) &data;
 
-                       cce = cne->classes;
-                       while (cce != NULL){ /* iterate over classes with same name */
-                               getchildproc(&data, cce, sizeof(classcache_class_entry));
-                               cce =(classcache_class_entry*) &data;
-                               
-                               if (cce->classobj != NULL) { /* get only loaded classes */
-                                       assert(j<ht->entries);
-                                       *classes_ptr[j]=cce->classobj;
+                       cce = cne->classes;
+                       while (cce != NULL){ iterate over classes with same name 
+                               getchildproc(&data, cce, sizeof(classcache_class_entry));
+                               cce =(classcache_class_entry*) &data;
+                                
+                               if (cce->classobj != NULL) { get only loaded classes 
+                                        assert(j<ht->entries);
+                                       * classes_ptr[j]=cce->classobj;
                                        j++;
                                }
                                cce = cce->next;
@@ -2573,10 +2559,12 @@ GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
                        cne = cne->hashlink;
                }
        }
-
        log_text ("GetLoadedClasses continue");
 
-       contdebuggee(0);
+       CLASSCACHE_UNLOCK();
+
+*/
 
        log_text ("GetLoadedClasses finished");
 
@@ -2728,7 +2716,7 @@ IsMethodObsolete (jvmtiEnv * env, jmethodID method,
 }
 
 
-/* *****************************************************************************
+/* SuspendThreadList **********************************************************
 
    
 
@@ -2742,14 +2730,15 @@ SuspendThreadList (jvmtiEnv * env, jint request_count,
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-    CHECK_CAPABILITY(env,can_suspend)
+    CHECK_CAPABILITY(env,can_suspend);
         
-  log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
+       log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
+
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* ResumeThreadList ***********************************************************
 
    
 
@@ -2762,9 +2751,10 @@ ResumeThreadList (jvmtiEnv * env, jint request_count,
        CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-    CHECK_CAPABILITY(env,can_suspend)
+    CHECK_CAPABILITY(env,can_suspend);
         
-  log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
+       log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
+
     return JVMTI_ERROR_NONE;
 }
 
@@ -2780,9 +2770,9 @@ GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
               jint max_frame_count, jvmtiFrameInfo * frame_buffer,
               jint * count_ptr)
 {
-       char* trace;
+       stacktracebuffer* trace;
        jvmtiError er;
-/*     int i,j;*/
+       int i,j;
 
        CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
@@ -2801,14 +2791,14 @@ GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
        er = getcacaostacktrace(&trace, thread);
        if (er==JVMTI_ERROR_NONE) return er;
 
-/*     todo: if ((trace->size >= start_depth) || ((trace->size * -1) > start_depth)) 
-       return JVMTI_ERROR_ILLEGAL_ARGUMENT; */
+       if ((trace->used >= start_depth) || ((trace->used * -1) > start_depth)) 
+               return JVMTI_ERROR_ILLEGAL_ARGUMENT; 
        
-/*     for (i=start_depth, j=0;i<trace->size;i++,j++) {
-               frame_buffer[j].method = (jmethodID)trace[i].start->method;
-         todo: location MachinePC not avilable - Linenumber not expected 
+       for (i=start_depth, j=0;i<trace->used;i++,j++) {
+               frame_buffer[j].method = (jmethodID)trace->entries[i].method;
+        /* todo: location BCI/MachinePC not avilable - Linenumber not expected */
                frame_buffer[j].location = 0;
-               }*/
+               }
        
     return JVMTI_ERROR_NONE;
 }
@@ -3169,7 +3159,7 @@ SetJNIFunctionTable (jvmtiEnv * env,
     
     if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
     _Jv_env->env = (void*)heap_allocate(sizeof(jniNativeInterface),true,NULL);
-    memcpy(_Jv_env->env, function_table, sizeof(jniNativeInterface));
+    memcpy((void*)_Jv_env->env, function_table, sizeof(jniNativeInterface));
     return JVMTI_ERROR_NONE;
 }
 
@@ -3327,11 +3317,9 @@ DisposeEnvironment (jvmtiEnv * env)
 {
        environment* cacao_env = (environment*)env;
        environment* tenvs = envs;
-    memset(&((cacao_env)->events[0]),0,sizeof(jvmtiEventModeLL)*
-                  (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
-    (cacao_env)->EnvironmentLocalStorage = NULL;
-       
-       if (tenvs!=cacao_env) {
+       jvmtiThreadLocalStorage *jtls, *tjtls;
+
+       if (tenvs != cacao_env) {
                while (tenvs->next != cacao_env) {
                        tenvs = tenvs->next;
                }
@@ -3339,7 +3327,30 @@ DisposeEnvironment (jvmtiEnv * env)
        } else
                envs = NULL;
 
-    /* let Boehm GC do the rest */
+       cacao_env->env=NULL;
+    memset(&(cacao_env->callbacks),0,sizeof(jvmtiEventCallbacks)*
+                  (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
+    memset(cacao_env->events,0,sizeof(jvmtiEventModeLL)*
+                  (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
+    cacao_env->EnvironmentLocalStorage = NULL;
+
+       jtls = cacao_env->tls;
+       while (jtls != NULL) {
+               tjtls = jtls;
+               jtls = jtls->next;
+               tjtls->next = NULL;
+       }
+       cacao_env->tls = NULL;
+
+
+       pthread_mutex_lock(&dbgcomlock);
+       dbgcom->running--;
+       if (dbgcom->running  == 0) {
+               TRAP;
+       }
+       pthread_mutex_unlock(&dbgcomlock);
+
+    /* let the GC do the rest */
     return JVMTI_ERROR_NONE;
 }
 
@@ -4103,12 +4114,7 @@ static jvmtiCapabilities JVMTI_Capabilities = {
   0,                           /* can_get_monitor_info */
   0,                           /* can_pop_frame */
   0,                           /* can_redefine_classes */
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-  /* current implementation does not work if called from another process */
-  0,                           /* can_signal_thread */
-#else
   0,                           /* can_signal_thread */
-#endif
   1,                           /* can_get_source_file_name */
   1,                           /* can_get_line_numbers */
   0,                           /* can_get_source_debug_extension */
@@ -4118,12 +4124,7 @@ static jvmtiCapabilities JVMTI_Capabilities = {
   0,                           /* can_generate_exception_events */
   0,                           /* can_generate_frame_pop_events */
   0,                           /* can_generate_breakpoint_events */
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
-  /* current implementation does not work if called from another process */
-  0,                           /* can_suspend */
-#else
   0,                           /* can_suspend */
-#endif
   0,                           /* can_redefine_any_class */
   0,                           /* can_get_current_thread_cpu_time */
   0,                           /* can_get_thread_cpu_time */
@@ -4299,7 +4300,7 @@ static struct jvmtiEnv_struct JVMTI_EnvTable = {
 void set_jvmti_phase(jvmtiPhase p) {
        genericEventData d;
 
-       fprintf (stderr,"set JVMTI pid %d phase %d\n",getpid(),p);
+       fprintf (stderr,"set JVMTI phase %d\n",p);
        fflush(stderr);
 
     switch (p) {
@@ -4313,7 +4314,7 @@ void set_jvmti_phase(jvmtiPhase p) {
                phase = p;
                d.ev = JVMTI_EVENT_VM_START;
                /* this event is sent during start or live phase */
-               log_text("debugger process - set brk in setthreadobj");
+               log_text("set sysbrk in setthreadobj");
                setsysbrkpt(SETTHREADOBJECTBRK,(void*)&setthreadobject);
         break;
     case JVMTI_PHASE_LIVE: 
@@ -4334,76 +4335,105 @@ void set_jvmti_phase(jvmtiPhase p) {
 
 jvmtiEnv* new_jvmtienv() {
     environment* env;
+       pid_t dbgserver;
+       char* comaddr;
 
        if (envs == NULL) {
                envs = heap_allocate(sizeof(environment),true,NULL);
                env = envs;
        } else {
                env = envs;
-               if (env != NULL) 
-                       while (env->next!=NULL) {
-                               env=env->next;
-                       }
-                       env = heap_allocate(sizeof(environment),true,NULL);
+               while (env->next != NULL) env = env->next;
+               env->next = heap_allocate(sizeof(environment),true,NULL);
+               env = env->next;
        }
+
        env->env = heap_allocate(sizeof(struct jvmtiEnv_struct),true,NULL);
     memcpy(env->env,&JVMTI_EnvTable,sizeof(struct jvmtiEnv_struct));
        memset(&(env->events),JVMTI_DISABLE,(JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM)*
                   sizeof(jvmtiEventModeLL));
     /* To possess a capability, the agent must add the capability.*/
-    memset(&(env->capabilities), 1, sizeof(jvmtiCapabilities));
+    memset(&(env->capabilities), 0, sizeof(jvmtiCapabilities));
     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();
+
+
        return (jvmtiEnv*)env;
 }
 
-void agentload(char* opt_arg) {
-       lt_dlhandle  handle;
-       lt_ptr       onload;
-       char *libname, *arg;
+void agentload(char* opt_arg, bool agentbypath, lt_dlhandle  *handle, char **libname) {
+       lt_ptr onload;
+       char *arg;
        int i=0,len;
        jint retval;
-       classinfo* ci;
+
        
        len = strlen(opt_arg);
        
-       while ((opt_arg[i]!='=')&&(i<len)) i++;
-       
-       libname=MNEW(char,i);
-       strncpy(libname,opt_arg,i-1);
-       libname[i-1]='\0';
-
-       arg=MNEW(char, len-i);
-       strcpy(arg,&opt_arg[i+1]);
+       /* separate argumtents */
+       while ((opt_arg[i]!='=')&&(i<=len)) i++;
+       arg = &opt_arg[i];
+
+       if (agentbypath) {
+               /* -agentpath */
+               *libname=heap_allocate(sizeof(char)*i,true,NULL);
+               strncpy(*libname,opt_arg,i-1);
+               (*libname)[i-1]='\0';
+       } else {
+               /* -agentlib */
+               *libname=heap_allocate(sizeof(char)*(i+7),true,NULL);
+               strncpy(*libname,"lib",3);
+               strncpy(&(*libname)[3],opt_arg,i-1);
+               strncpy(&(*libname)[i+2],".so",3);
+       }
 
        /* try to open the library */
-
-       if (!(handle = lt_dlopen(libname)))
-               return;
-
+       lt_dlinit();
+       if (!(*handle = lt_dlopen(*libname))) {
+               fprintf(stderr,"Could not find agent library: %s (%s)\n",*libname,lt_dlerror());
+               vm_shutdown(1);
+       }
+               
        /* resolve Agent_OnLoad function */
-       onload = lt_dlsym(handle, "Agent_OnLoad");
-       if (onload == NULL) {
-               fprintf(stderr, "unable to load Agent_OnLoad function in %s\n", libname);
-               exit(1);
+       if (!(onload = lt_dlsym(*handle, "Agent_OnLoad"))) {
+               fprintf(stderr,"unable to load Agent_OnLoad function in %s (%s)\n",*libname,lt_dlerror());
+               vm_shutdown(1);
        }
 
        /* resolve Agent_UnLoad function */
-       unload = lt_dlsym(handle, "Agent_Unload");
-
-       /* add library to native library hashtable */
-       ci = load_class_from_sysloader(utf_new_char("java.lang.Object"));
-       native_hashtable_library_add(utf_new_char(libname), ci->classloader, handle);
+       unload = lt_dlsym(*handle, "Agent_Unload");
 
        retval = 
                ((JNIEXPORT jint JNICALL (*) (JavaVM *vm, char *options, void *reserved))
-                onload) ((JavaVM*) &_Jv_JNIInvokeInterface, arg, NULL);
-       
-       MFREE(libname,char,i);
-       MFREE(arg,char,len-i);
-       
+                onload) ((JavaVM *) _Jv_jvm, arg, NULL);
+
        if (retval != 0) exit (retval);
 }
 
index 3781e463530dc9cb360072fb0e5d0bb6ec6840dc..1ff62419432b45c153f7b2f890b77bc7f5efae35 100644 (file)
    Changes:             
 
    
-   $Id: jvmti.h 4661 2006-03-21 00:04:59Z motse $
+   $Id: jvmti.h 4892 2006-05-06 18:29:55Z motse $
 
 */
 #ifndef _JVMTI_H
 #define _JVMTI_H
 
 #include "native/jni.h"
-#include "native/include/java_lang_String.h"
 #include <sys/types.h>
 
 #define JVMTI_VERSION_1_0 0x30010000
+#define JVMTI_VERSION     JVMTI_VERSION_1_0 
 
 typedef jobject jthread;
 typedef jobject jthreadGroup;
diff --git a/src/native/vm/VMMethod.c b/src/native/vm/VMMethod.c
new file mode 100644 (file)
index 0000000..3d49003
--- /dev/null
@@ -0,0 +1,109 @@
+/* src/native/vm/VMMethod.c - jdwp->jvmti interface
+
+Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+J. Wenninger, Institut f. Computersprachen - TU Wien
+
+This file is part of CACAO.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2, or (at
+your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.
+
+Contact: cacao@cacaojvm.org
+
+Authors: Samuel Vinson
+
+Changes: 
+
+
+$Id: $
+
+*/
+
+#include "toolbox/logging.h"
+#include "native/jni.h"
+#include "native/include/gnu_classpath_jdwp_VMMethod.h"
+#include "vm/stringlocal.h"
+#include "toolbox/logging.h"
+
+/*
+ * Class:     gnu/classpath/jdwp/VMMethod
+ * Method:    getName
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT struct java_lang_String* JNICALL Java_gnu_classpath_jdwp_VMMethod_getName(JNIEnv *env, struct gnu_classpath_jdwp_VMMethod* this)
+{
+       classinfo  *c;
+       methodinfo *m;
+
+       c = (classinfo *)this->_class;
+       m = &(c->methods[this->_methodId]);
+       log_message_utf("Method_getName %s", m->name);
+       return javastring_new(m->name);
+}
+
+
+/*
+ * Class:     gnu/classpath/jdwp/VMMethod
+ * Method:    getSignature
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT struct java_lang_String* JNICALL Java_gnu_classpath_jdwp_VMMethod_getSignature(JNIEnv *env, struct gnu_classpath_jdwp_VMMethod* this)
+{
+       log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       return 0;
+}
+
+
+/*
+ * Class:     gnu/classpath/jdwp/VMMethod
+ * Method:    getModifiers
+ * Signature: ()I
+ */
+JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMMethod_getModifiers(JNIEnv *env, struct gnu_classpath_jdwp_VMMethod* this)
+{
+       classinfo  *c;
+       methodinfo *m;
+
+       c = (classinfo *) this->_class;
+       m = &(c->methods[this->_methodId]);
+
+       return m->flags;
+}
+
+
+/*
+ * Class:     gnu/classpath/jdwp/VMMethod
+ * Method:    getLineTable
+ * Signature: ()Lgnu/classpath/jdwp/util/LineTable;
+ */
+JNIEXPORT struct gnu_classpath_jdwp_util_LineTable* JNICALL Java_gnu_classpath_jdwp_VMMethod_getLineTable(JNIEnv *env, struct gnu_classpath_jdwp_VMMethod* this)
+{
+       log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       return 0;
+}
+
+
+/*
+ * Class:     gnu/classpath/jdwp/VMMethod
+ * Method:    getVariableTable
+ * Signature: ()Lgnu/classpath/jdwp/util/VariableTable;
+ */
+JNIEXPORT struct gnu_classpath_jdwp_util_VariableTable* JNICALL Java_gnu_classpath_jdwp_VMMethod_getVariableTable(JNIEnv *env, struct gnu_classpath_jdwp_VMMethod* this)
+{
+       log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       return 0;
+}
index 0a5bfaa37ec1030de6f0d75a6a5c3beab927a1e4..2d220093343461cecafa96f58ea99fd7db4a606f 100644 (file)
@@ -26,10 +26,10 @@ Contact: cacao@cacaojvm.org
 
 Authors: Martin Platter
 
-Changes: 
+Changes: Samuel Vinson
 
 
-$Id: VMVirtualMachine.c 4661 2006-03-21 00:04:59Z motse $
+$Id: VMVirtualMachine.c 4892 2006-05-06 18:29:55Z motse $
 
 */
 
@@ -43,7 +43,7 @@ $Id: VMVirtualMachine.c 4661 2006-03-21 00:04:59Z motse $
 #include "native/include/gnu_classpath_jdwp_event_EventRequest.h"
 #include "native/include/gnu_classpath_jdwp_VMVirtualMachine.h"
 #include "native/jvmti/jvmti.h"
-#include "native/jvmti/cacaodbg.h"
+#include "native/jvmti/VMjdwp.h"
 #include <string.h>
 
 
@@ -54,7 +54,7 @@ $Id: VMVirtualMachine.c 4661 2006-03-21 00:04:59Z motse $
  */
 JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_suspendThread(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1)
 {
-    (*remotedbgjvmtienv)->SuspendThread(remotedbgjvmtienv, (jthread) par1);
+    (*jvmtienv)->SuspendThread(jvmtienv, (jthread) par1);
 }
 
 /*
@@ -64,7 +64,7 @@ JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_suspendThread(JN
  */
 JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_resumeThread(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1)
 {
-    (*remotedbgjvmtienv)->ResumeThread(remotedbgjvmtienv, (jthread) par1);
+    (*jvmtienv)->ResumeThread(jvmtienv, (jthread) par1);
 }
 
 
@@ -87,7 +87,7 @@ JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getAllLoadedClasse
     jint count;
     jclass* classes;
 
-    (*remotedbgjvmtienv)->GetLoadedClasses(remotedbgjvmtienv, &count, &classes);
+    (*jvmtienv)->GetLoadedClasses(jvmtienv, &count, &classes);
     return count;
 }
 
@@ -107,9 +107,9 @@ JNIEXPORT struct java_util_Iterator* JNICALL Java_gnu_classpath_jdwp_VMVirtualMa
        jvmtiError err;
        char* errdesc;
 
-       if (JVMTI_ERROR_NONE != (err= (*remotedbgjvmtienv)->
-               GetLoadedClasses(remotedbgjvmtienv, &classcount, &classes))) {
-               (*remotedbgjvmtienv)->GetErrorName(remotedbgjvmtienv,err, &errdesc);
+       if (JVMTI_ERROR_NONE != (err= (*jvmtienv)->
+               GetLoadedClasses(jvmtienv, &classcount, &classes))) {
+               (*jvmtienv)->GetErrorName(jvmtienv,err, &errdesc);
                fprintf(stderr,"jvmti error: %s\n",errdesc);
                fflush(stderr);
 /*             env->ThrowNew(env,ec,"jvmti error occoured");*/
@@ -119,6 +119,7 @@ JNIEXPORT struct java_util_Iterator* JNICALL Java_gnu_classpath_jdwp_VMVirtualMa
 
        /* Arrays.asList(Object[] classes)->List.Iterator()->Iterator */
        joa = (*env)->NewObjectArray(env, (jsize)classcount, cl , NULL);
+       if (!joa) return NULL;
 
        for (i = 0; i < classcount; i++) 
                (*env)->SetObjectArrayElement(env,joa,(jsize)i, (jobject)classes[i]);
@@ -134,8 +135,8 @@ JNIEXPORT struct java_util_Iterator* JNICALL Java_gnu_classpath_jdwp_VMVirtualMa
 
        cl = (*env)->FindClass(env,"java.util.List");
        if (!cl) return NULL;
-       m = (*env)->GetMethodID(env,cl,"Iterator","()Ljava/util/Iterator;");
-
+       m = (*env)->GetMethodID(env,cl,"iterator","()Ljava/util/Iterator;");
+       if (!m) return NULL;
        oi = (*env)->CallObjectMethod(env,*ol,m);
                
        return (struct java_util_Iterator*)oi;
@@ -147,7 +148,7 @@ JNIEXPORT struct java_util_Iterator* JNICALL Java_gnu_classpath_jdwp_VMVirtualMa
  */
 JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getClassStatus(JNIEnv *env, jclass clazz, struct java_lang_Class* par1) {
        jint status;
-       (*remotedbgjvmtienv)->GetClassStatus(remotedbgjvmtienv, (jclass) par1, &status);
+       (*jvmtienv)->GetClassStatus(jvmtienv, (jclass) par1, &status);
        return status;
 }
 
@@ -158,6 +159,7 @@ JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getClassStatus(JNI
  */
 JNIEXPORT java_objectarray* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getAllClassMethods(JNIEnv *env, jclass clazz, struct java_lang_Class* par1) {
     log_text ("VMVirtualMachine_getAllClassMethods: IMPLEMENT ME !!!");
+       return NULL;
 }
 
 
@@ -168,6 +170,7 @@ JNIEXPORT java_objectarray* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_get
  */
 JNIEXPORT struct gnu_classpath_jdwp_VMMethod* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getClassMethod(JNIEnv *env, jclass clazz, struct java_lang_Class* par1, s8 par2) {
     log_text ("VMVirtualMachine_getAllClassMethod: IMPLEMENT ME !!!");
+       return NULL;
 }
 
 
@@ -179,7 +182,7 @@ JNIEXPORT struct gnu_classpath_jdwp_VMMethod* JNICALL Java_gnu_classpath_jdwp_VM
 JNIEXPORT struct java_util_ArrayList* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getFrames(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1, s4 par2, s4 par3) {
     log_text ("VMVirtualMachine_getFrames - IMPLEMENT ME!!!");
 /*     jclass ec = (*env)->FindClass(env,"gnu/classpath/jdwp/JdwpInternalErrorException");
-       if (JVMTI_ERROR_NONE != (*remotedbgjvmtienv)->GetClassStatus(remotedbgjvmtienv, par1, &status))
+       if (JVMTI_ERROR_NONE != (*jvmtienv)->GetClassStatus(jvmtienv, par1, &status))
        env->ThrowNew(env,ec,"jvmti error occoured");*/
        return 0;
 }
@@ -203,7 +206,7 @@ JNIEXPORT struct gnu_classpath_jdwp_VMFrame* JNICALL Java_gnu_classpath_jdwp_VMV
  */
 JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getFrameCount(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1) {
        jint count;
-       (*remotedbgjvmtienv)->GetFrameCount(remotedbgjvmtienv, (jthread)par1, &count);
+       (*jvmtienv)->GetFrameCount(jvmtienv, (jthread)par1, &count);
        return count;
 }
 
@@ -215,7 +218,7 @@ JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getFrameCount(JNIE
  */
 JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getThreadStatus(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1) {
        jint status;
-       if (JVMTI_ERROR_NONE != (*remotedbgjvmtienv)->GetThreadState(remotedbgjvmtienv, (jthread)par1, &status))
+       if (JVMTI_ERROR_NONE != (*jvmtienv)->GetThreadState(jvmtienv, (jthread)par1, &status))
                return 0;
        if (status && JVMTI_THREAD_STATE_ALIVE) {
                if (status && JVMTI_THREAD_STATE_WAITING) {             
@@ -265,8 +268,8 @@ JNIEXPORT struct java_lang_String* JNICALL Java_gnu_classpath_jdwp_VMVirtualMach
        char* srcname;
        jstring str;
 
-    (*remotedbgjvmtienv)->
-               GetSourceFileName(remotedbgjvmtienv, (jclass)par1, &srcname);
+    (*jvmtienv)->
+               GetSourceFileName(jvmtienv, (jclass)par1, &srcname);
        str = (*env)->NewString(env,(jchar*)srcname,(jsize)strlen(srcname));
 
        return (struct java_lang_String*)str;
@@ -312,8 +315,8 @@ JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_registerEvent(JN
        kindid = (*env)->GetFieldID(env, erc, "_kind", "B");
        kind = (*env)->GetByteField(env, (jobject)par1, kindid);
 
-       (*remotedbgjvmtienv)->
-               SetEventNotificationMode(remotedbgjvmtienv, JVMTI_ENABLE, 
+       (*jvmtienv)->
+               SetEventNotificationMode(jvmtienv, JVMTI_ENABLE, 
                                                                 EventKind2jvmtiEvent(kind), NULL);
 
        /* todo: error handling, suspend policy */
@@ -335,8 +338,8 @@ JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_unregisterEvent(
        kindid = (*env)->GetFieldID(env, erc, "_kind", "B");
        kind = (*env)->GetByteField(env, (jobject)par1, kindid);
 
-       (*remotedbgjvmtienv)->
-               SetEventNotificationMode(remotedbgjvmtienv, JVMTI_DISABLE, 
+       (*jvmtienv)->
+               SetEventNotificationMode(jvmtienv, JVMTI_DISABLE, 
                                                                 EventKind2jvmtiEvent(kind), NULL);
 
        /* todo: error handling, suspend policy */
index 6aeecd43b48ec619b7322bf2f87c0e5c1770a21b..93c04ce79d00c561d9b1657c5d95b72ca0a45c6c 100644 (file)
@@ -26,7 +26,7 @@
 
    Authors: Christian Thalinger
 
-   Changes:
+   Changes: Martin Platter
 
    $Id: finalizer.c 4357 2006-01-22 23:33:38Z twisti $
 
@@ -511,6 +511,15 @@ bool vm_create(JavaVMInitArgs *vm_args)
        s4    opt;
        s4    i, j, k;
 
+
+#if defined(ENABLE_JVMTI)
+       lt_dlhandle  handle;
+       char* libname;
+       bool agentbypath = false;;
+#endif
+       
+
+
        /* check the JNI version requested */
 
        switch (vm_args->version) {
@@ -583,10 +592,7 @@ bool vm_create(JavaVMInitArgs *vm_args)
 
 #if defined(ENABLE_JVMTI)
        /* initialize JVMTI related  **********************************************/
-       jvmtibrkpt.brk=NULL;
-       jvmtibrkpt.num=0;
-       jvmtibrkpt.size=0;
-       jdwp = jvmti = dbgprocess = false;
+       jdwp = jvmti = false;
 #endif
 
        /* initialize properties before commandline handling */
@@ -713,7 +719,9 @@ bool vm_create(JavaVMInitArgs *vm_args)
                        }
                        
                        break;
+
                case OPT_AGENTPATH:
+                       agentbypath = true;
                case OPT_AGENTLIB:
                        jvmti=true;
                        agentarg = opt_arg;
@@ -1053,18 +1061,11 @@ bool vm_create(JavaVMInitArgs *vm_args)
        }
 
 #if defined(ENABLE_JVMTI)
-       /* The fork has to occure before threads a created because threads  are 
-          not forked correctly (see man pthread_atfork). Varibale dbgprocess 
-          stores information whether this is the debugger or debuggee process. */
-       if (jvmti || jdwp) {
+       if (jvmti) {
                set_jvmti_phase(JVMTI_PHASE_ONLOAD);
-               dbgprocess = cacaodbgfork();
-       }
-
-       if (dbgprocess && jvmti) { /* is this the parent/debugger process ? */
-               agentload(agentarg);
-               set_jvmti_phase(JVMTI_PHASE_PRIMORDIAL);
+               agentload(agentarg, agentbypath, &handle, &libname);
        }
+       set_jvmti_phase(JVMTI_PHASE_PRIMORDIAL);
 #endif
 
 
@@ -1211,6 +1212,13 @@ bool vm_create(JavaVMInitArgs *vm_args)
 /*             throw_main_exception_exit(); */
 #endif
 
+#if defined(ENABLE_JVMTI)
+       if (jvmti) {
+               /* add agent library to native library hashtable */
+               native_hashtable_library_add(utf_new_char(libname), class_java_lang_Object->classloader, handle);
+       }
+#endif
+
        /* increment the number of VMs */
 
        vms++;
@@ -1265,10 +1273,8 @@ void vm_exit(s4 status)
        assert(class_java_lang_System->state & CLASS_LOADED);
 
 #if defined(ENABLE_JVMTI)
-       if (dbgprocess) {
-               set_jvmti_phase(JVMTI_PHASE_DEAD);
-               if (jvmti) agentunload();
-       }
+       set_jvmti_phase(JVMTI_PHASE_DEAD);
+       if (jvmti) agentunload();
 #endif
 
        if (!link_class(class_java_lang_System))
@@ -1305,13 +1311,6 @@ void vm_exit(s4 status)
 
 void vm_shutdown(s4 status)
 {
-#if defined(ENABLE_JVMTI)
-       if (dbgprocess) {
-               set_jvmti_phase(JVMTI_PHASE_DEAD);
-               if (jvmti) agentunload();
-               ipcrm();
-       }
-#endif
        if (opt_verbose 
 #if defined(ENABLE_STATISTICS)
                || opt_getcompilingtime || opt_stat
@@ -1338,12 +1337,6 @@ void vm_shutdown(s4 status)
 
 void vm_exit_handler(void)
 {
-#if defined(ENABLE_JVMTI)
-       if (jvmti && jdwp) set_jvmti_phase(JVMTI_PHASE_DEAD);
-       if (jvmti) agentunload();
-       ipcrm();
-#endif
-
 #if !defined(NDEBUG)
        if (showmethods)
                class_showmethods(mainclass);