dist: RedHat 6.1 kernel: 2.2.13 jdk: Blackdown 1.2.2RC3 glibc: 2.1.2-11 My story so far: I use the invocation api to load the jvm and run some java code. If the thread I use to run the code is the main thread, everything works fine. If I create a thread (pthread_create) to run the code, I get a segv when that thread exits. This code runs fine on every Solaris or win32 (1.1 or 1.2) jvm that I've tried. I am aware that there are problems with using the green thread version with the invocation api, but to the best of my knowledge I am using native threads. To demonstrate the problem, I modified jdk1.2.2/src/launcher/java.c to take a "-createthread" flag, which runs the java code in a new thread: [chrisc@new-joker launcher]$ ./java Hello Hello. [chrisc@new-joker launcher]$ ./java -createthread Hello Hello. SIGSEGV 11* segmentation violation Full thread dump Classic VM (Linux_JDK_RC3, native threads): "Finalizer" (TID:0x2b90e320, sys_thread_t:0x80d0dc8, state:CW, native ID:0xc04) prio=8 at java.lang.Object.wait(Native Method) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:112) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:127) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:174) "Reference Handler" (TID:0x2b90e3b0, sys_thread_t:0x80caa50, state:CW, native ID:0x803) prio=10 at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:424) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:114) "SIGQUIT handler" (TID:0x2b90e3e0, sys_thread_t:0x80d0290, state:R, native ID:0x402) prio=5 "main" (TID:0x2b90e1e0, sys_thread_t:0x80536c8, state:R, native ID:0x400) prio=5 Monitor Cache Dump: java.lang.ref.ReferenceQueue$Lock@2B90E338/2B944028: <unowned> Waiting to be notified: "Finalizer" (0x80d0dc8) java.lang.ref.Reference$Lock@2B90E3C0/2B943B20: <unowned> Waiting to be notified: "Reference Handler" (0x80caa50) Registered Monitor Dump: PCMap lock: <unowned> utf8 hash table: <unowned> JNI pinning lock: <unowned> JNI global reference lock: <unowned> BinClass lock: <unowned> Class linking lock: <unowned> System class loader lock: <unowned> Code rewrite lock: <unowned> Heap lock: <unowned> Monitor cache lock: <unowned> Thread queue lock: <unowned> Under gdb, I see that the crash is in pthread_exit in the thread which I created that ran the java code: (gdb) where #0 0x8126773 in ?? () #1 0x2aacb6e9 in pthread_exit (retval=0x0) at join.c:35 #2 0x2aacbed0 in pthread_allocate_stack (attr=0x7f1ffe60, default_new_thread=0x7f3ffe60, pagesize=716003008, out_new_thread=0x0, out_new_thread_bottom=0x0, out_guardaddr=0x1005, out_guardsize=0x46db) at manager.c:216 (gdb) info thr * 6 Thread 18139 0x8126773 in ?? () 5 Thread 18138 0x2ab6358b in __sigsuspend (set=0x7f3ff93c) at ../sysdeps/unix/sysv/linux/sigsuspend.c:48 4 Thread 18137 0x2ab6358b in __sigsuspend (set=0x7f5ff93c) at ../sysdeps/unix/sysv/linux/sigsuspend.c:48 3 Thread 18136 0x2ab6358b in __sigsuspend (set=0x7f7ffae0) at ../sysdeps/unix/sysv/linux/sigsuspend.c:48 2 Thread 18134 (initial thread) 0x2ab6358b in __sigsuspend (set=0x7ffffa14) at ../sysdeps/unix/sysv/linux/sigsuspend.c:48 1 Thread 18135 (manager thread) 0x2abef320 in __poll (fds=0x80d3d90, nfds=1, timeout=2000) at ../sysdeps/unix/sysv/linux/poll.c:45 To reproduce the problem: * Extract the source from /usr/local/jdk1.2.2/src.jar using "jar xvf src.jar" * cd src/launcher * Patch java.c with the included diffs. * Compile the launcher ("java") using: $(CC) -g -Wall -L/usr/local/jdk1.2.2/jre/lib/i386/classic -I/usr/local/jdk1.2.2/include -I/usr/local/jdk1.2.2/include/linux -D_GNU_SOURCE -D_REENTRANT=1 java.c java_md.c -o java -ldl -lpthread -ljvm (I used egcs.) * Run as above. Any insights/guesses/suggestions would be greatly appreciated. At this point, I'll probably attempt to build the jdk from the source using the Blackdown patches. Thanks, Chris *** java.c Sat Jan 1 16:30:32 2000 --- javax.c Sat Jan 1 19:45:27 2000 *************** *** 29,34 **** --- 29,35 ---- #include <stdio.h> #include <stdlib.h> #include <string.h> + #include <pthread.h> #include <jni.h> #include "java.h" *************** *** 38,43 **** --- 39,45 ---- #endif static jboolean printVersion = JNI_FALSE; + static jboolean createThread = JNI_FALSE; static char *progname; jboolean debug = JNI_FALSE; *************** *** 75,96 **** /* * Entry point. */ int ! main(int argc, char **argv) { - JavaVM *vm = 0; JNIEnv *env = 0; - char *jarfile = 0; - char *classname = 0; char *s = 0; - jclass mainClass; - jmethodID mainID; - jobjectArray mainArgs; - int ret; InvocationFunctions ifn; char *jvmtype = 0; jboolean jvmspecified = JNI_FALSE; /* Assume no option specified. */ jlong start, end; if (getenv("_JAVA_LAUNCHER_DEBUG") != 0) { debug = JNI_TRUE; --- 77,100 ---- /* * Entry point. */ + int argc; + char **argv; + JavaVM *vm = 0; + char *jarfile = 0; + char *classname = 0; + int ! initialize_vm(jboolean *prun) { JNIEnv *env = 0; char *s = 0; InvocationFunctions ifn; char *jvmtype = 0; jboolean jvmspecified = JNI_FALSE; /* Assume no option specified. */ jlong start, end; + int ret; + + *prun = JNI_FALSE; if (getenv("_JAVA_LAUNCHER_DEBUG") != 0) { debug = JNI_TRUE; *************** *** 110,116 **** } ifn.CreateJavaVM = 0; ifn.GetDefaultJavaVMInitArgs = 0; if (!LoadJavaVM(jvmtype, &ifn)) ! return 1; /* Grab the program name */ progname = *argv++; --- 114,120 ---- } ifn.CreateJavaVM = 0; ifn.GetDefaultJavaVMInitArgs = 0; if (!LoadJavaVM(jvmtype, &ifn)) ! return 1; /* Grab the program name */ progname = *argv++; *************** *** 129,135 **** /* Preprocess wrapper arguments */ TranslateDashJArgs(&argc, &argv); if (!AddApplicationOptions()) ! return 1; #endif /* Set default CLASSPATH */ --- 133,139 ---- /* Preprocess wrapper arguments */ TranslateDashJArgs(&argc, &argv); if (!AddApplicationOptions()) ! return 1; #endif /* Set default CLASSPATH */ *************** *** 145,151 **** if (ifn.GetDefaultJavaVMInitArgs(&args) != JNI_OK || args.classpath == 0) { fprintf(stderr, "Could not get default system class path.\n"); ! return 1; } buf = MemAlloc(strlen(args.classpath) + strlen(s) + 2); sprintf(buf, "%s%c%s", args.classpath, PATH_SEPARATOR, s); --- 149,155 ---- if (ifn.GetDefaultJavaVMInitArgs(&args) != JNI_OK || args.classpath == 0) { fprintf(stderr, "Could not get default system class path.\n"); ! return 1; } buf = MemAlloc(strlen(args.classpath) + strlen(s) + 2); sprintf(buf, "%s%c%s", args.classpath, PATH_SEPARATOR, s); *************** *** 158,164 **** /* Parse command line options */ if (!ParseArguments(&argc, &argv, &jarfile, &classname, &ret)) { ! return ret; } /* Override class path if -jar flag was specified */ --- 162,168 ---- /* Parse command line options */ if (!ParseArguments(&argc, &argv, &jarfile, &classname, &ret)) { ! return ret; } /* Override class path if -jar flag was specified */ *************** *** 172,195 **** start = CounterGet(); if (!InitializeJVM(&vm, &env, &ifn)) { fprintf(stderr, "Could not create the Java virtual machine.\n"); ! return 1; } if (printVersion) { PrintJavaVersion(env); if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionDescribe(env); ! ret = 1; } else { ! ret = 0; } - goto leave; } /* If the user specified neither a class name or a JAR file */ if (jarfile == 0 && classname == 0) { PrintUsage(); ! goto leave; } if (debug) { --- 176,198 ---- start = CounterGet(); if (!InitializeJVM(&vm, &env, &ifn)) { fprintf(stderr, "Could not create the Java virtual machine.\n"); ! return 1; } if (printVersion) { PrintJavaVersion(env); if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionDescribe(env); ! return 1; } else { ! return 0; } } /* If the user specified neither a class name or a JAR file */ if (jarfile == 0 && classname == 0) { PrintUsage(); ! return 0; } if (debug) { *************** *** 198,203 **** --- 201,225 ---- (jint)Counter2Micros(end-start)); } + *prun = JNI_TRUE; + return 0; + } + + void * + run_main(void *pret_arg) + { + int *pret = (int *)pret_arg; + jclass mainClass; + jmethodID mainID; + jobjectArray mainArgs; + JNIEnv *env = 0; + + if ((*vm)->AttachCurrentThread(vm, (void **)&env, NULL) != 0) { + fprintf(stderr, "Could not attach thread.\n"); + *pret = 1; + return NULL; + } + /* At this stage, argc/argv have the applications' arguments */ if (debug) { int i = 0; *************** *** 208,231 **** } } - ret = 1; - /* Get the application's main class */ if (jarfile != 0) { jstring mainClassName = GetMainClassName(env, jarfile); if (mainClassName == NULL) { fprintf(stderr, "Failed to load Main-Class manifest attribute " "from\n%s\n", jarfile); ! goto leave; } if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionDescribe(env); ! goto leave; } classname = (char *)(*env)->GetStringUTFChars(env, mainClassName, 0); if (classname == NULL) { (*env)->ExceptionDescribe(env); ! goto leave; } mainClass = LoadClass(env, classname); (*env)->ReleaseStringUTFChars(env, mainClassName, classname); --- 230,254 ---- } } /* Get the application's main class */ if (jarfile != 0) { jstring mainClassName = GetMainClassName(env, jarfile); if (mainClassName == NULL) { fprintf(stderr, "Failed to load Main-Class manifest attribute " "from\n%s\n", jarfile); ! *pret = 1; ! return NULL; } if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionDescribe(env); ! *pret = 1; ! return NULL; } classname = (char *)(*env)->GetStringUTFChars(env, mainClassName, 0); if (classname == NULL) { (*env)->ExceptionDescribe(env); ! *pret = 1; ! return NULL; } mainClass = LoadClass(env, classname); (*env)->ReleaseStringUTFChars(env, mainClassName, classname); *************** *** 234,240 **** } if (mainClass == NULL) { (*env)->ExceptionDescribe(env); ! goto leave; } /* Get the application's main method */ --- 257,264 ---- } if (mainClass == NULL) { (*env)->ExceptionDescribe(env); ! *pret = 1; ! return NULL; } /* Get the application's main method */ *************** *** 246,259 **** } else { fprintf(stderr, "No main method found in specified class.\n"); } ! goto leave; } /* Build argument array */ mainArgs = NewPlatformStringArray(env, argv, argc); if (mainArgs == NULL) { (*env)->ExceptionDescribe(env); ! goto leave; } /* Invoke main method. */ --- 270,285 ---- } else { fprintf(stderr, "No main method found in specified class.\n"); } ! *pret = 1; ! return NULL; } /* Build argument array */ mainArgs = NewPlatformStringArray(env, argv, argc); if (mainArgs == NULL) { (*env)->ExceptionDescribe(env); ! *pret = 1; ! return NULL; } /* Invoke main method. */ *************** *** 265,271 **** stack trace as ExceptionDescribe and could never actually be overridden by application programs. */ (*env)->ExceptionDescribe(env); ! goto leave; } /* --- 291,298 ---- stack trace as ExceptionDescribe and could never actually be overridden by application programs. */ (*env)->ExceptionDescribe(env); ! *pret = 1; ! return NULL; } /* *************** *** 273,286 **** * the application's main method exits. */ if ((*vm)->DetachCurrentThread(vm) != 0) { ! fprintf(stderr, "Could not detach main thread.\n"); ! goto leave; } - ret = 0; ! leave: (*vm)->DestroyJavaVM(vm); ! return ret; } /* --- 300,349 ---- * the application's main method exits. */ if ((*vm)->DetachCurrentThread(vm) != 0) { ! fprintf(stderr, "Could not detach thread.\n"); ! *pret = 1; ! return NULL; } ! *pret = 0; ! return NULL; ! } ! ! void ! destroy_vm(void) ! { (*vm)->DestroyJavaVM(vm); ! } ! ! int ! main(int argc_local, char **argv_local) ! { ! pthread_t tid; ! int ret; ! jboolean run; ! ! argc = argc_local; ! argv = argv_local; ! ! if ((ret = initialize_vm(&run)) != 0) ! exit(ret); ! ! if (run) { ! if (createThread) { ! pthread_create(&tid, NULL, run_main, &ret); ! pthread_join(tid, NULL); ! } else { ! run_main(&ret); ! } ! ! if (ret != 0) ! exit(ret); ! ! destroy_vm(); ! } ! ! exit(0); ! return -1; } /* *************** *** 358,363 **** --- 421,428 ---- } else if (strcmp(arg, "-version") == 0) { printVersion = JNI_TRUE; return JNI_TRUE; + } else if (strcmp(arg, "-createthread") == 0) { + createThread = JNI_TRUE; } else if (strcmp(arg, "-X") == 0) { *pret = PrintXUsage(); return JNI_FALSE; ---------------------------------------------------------------------- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]