When I started my tests with several threads the last time, I noticed that sync points in a spawned secondary thread were commented out and treated as sync points “during VM termination”. It was clear why: I declared that VM termination began as soon as the main method was exited.
That hardly corresponds to the end of most real programs, particularly GUI programs. I am now instrumenting
Thread.exit again to keep track of the number of live user threads. Since thread 0, the main thread, never explicitly gets created, the count starts at 1 and gets incremented at every
Thread.start and decremented at every
Thread.exit triggers a push of the sync points to make sure they are received. If the count of live user threads reaches 0 on leaving
Thread.exit, immediate transfers are enabled.
Regardless of the number of threads spawned, all synchronization points after entering the main method are now labelled as active except for exactly the eight synchronization points that occur in the ominous “DestroyJavaVM”: The thread ID of that thread varies, of course, it’s not always 9, as in earlier tests, but the sequence is always the same: “1 tid; 2 tid; 1 tid; 1 tid; 2 tid; 1 tid; 2 tid; 2 tid”.
// 1 18 // 000030af 000b 0005 java.lang.Shutdown.shutdown()V PC=5 // 2 18 // 000030af 000b 004e java.lang.Shutdown.shutdown()V PC=78 // 1 18 // 000030af 000b 006e java.lang.Shutdown.shutdown()V PC=110 // 1 18 // 000030af 0009 0005 java.lang.Shutdown.sequence()V PC=5 // 2 18 // 000030af 0009 0047 java.lang.Shutdown.sequence()V PC=71 // 1 18 // 000030af 0009 006a java.lang.Shutdown.sequence()V PC=106 // 2 18 // 000030af 0009 0098 java.lang.Shutdown.sequence()V PC=152 // 2 18 // 000030af 000b 0097 java.lang.Shutdown.shutdown()V PC=151
Thread.exit are logged as sync points 4 and 5. I haven’t decided if I’ll treat them as comments and skip them during replay, or if I’ll enforce their existence. Probably the latter.
I haven’t yet added more parts of the replay algorithm back, but at least I’m on my way.