1 /**
   2  *  @test
   3  *  @bug 6459476
   4  *  @summary Debuggee is blocked,  looks like running
   5  *
   6  *  @author jjh
   7  *
   8  *  @run build TestScaffold VMConnection TargetListener TargetAdapter
   9  *  @run compile -g InterruptHangTest.java
  10  *  @run driver InterruptHangTest
  11  */
  12 import com.sun.jdi.*;
  13 import com.sun.jdi.event.*;
  14 import com.sun.jdi.request.*;
  15 
  16 /*
  17  * Debuggee has two threads.  Debugger keeps stepping in
  18  * the first thread.  The second thread keeps interrupting the first
  19  * thread.  If a long time goes by with the debugger not getting
  20  * a step event, the test fails.
  21  */
  22 class InterruptHangTarg {
  23     public static String sync = "sync";
  24     public static void main(String[] args){
  25         int answer = 0;
  26         System.out.println("Howdy!");
  27         Interruptor interruptorThread = new Interruptor(Thread.currentThread());
  28 
  29         synchronized(sync) {
  30             interruptorThread.start();
  31             try {
  32                 sync.wait();
  33             } catch (InterruptedException ee) {
  34                 System.out.println("Debuggee interruptee: interrupted before starting loop");
  35             }
  36         }
  37 
  38         // Debugger will keep stepping thru this loop
  39         for (int ii = 0; ii < 200; ii++) {
  40             answer++;
  41             try {
  42                 // Give other thread a chance to run
  43                 Thread.sleep(100);
  44             } catch (InterruptedException ee) {
  45                 System.out.println("Debuggee interruptee: interrupted at iteration: "
  46                                    + ii);
  47             }
  48         }
  49         // Kill the interrupter thread
  50         interruptorThread.interrupt();
  51         System.out.println("Goodbye from InterruptHangTarg!");
  52     }
  53 }
  54 
  55 class Interruptor extends Thread {
  56     Thread interruptee;
  57     Interruptor(Thread interruptee) {
  58         this.interruptee = interruptee;
  59     }
  60 
  61     public void run() {
  62         synchronized(InterruptHangTarg.sync) {
  63             InterruptHangTarg.sync.notify();
  64         }
  65 
  66         int ii = 0;
  67         while(true) {
  68             ii++;
  69             interruptee.interrupt();
  70             try {
  71                 Thread.sleep(10);
  72             } catch (InterruptedException ee) {
  73                 System.out.println("Debuggee Interruptor: finished after " +
  74                                    ii + " iterrupts");
  75                 break;
  76             }
  77 
  78         }
  79     }
  80 }
  81 
  82     /********** test program **********/
  83 
  84 public class InterruptHangTest extends TestScaffold {
  85     ThreadReference mainThread;
  86     Thread timerThread;
  87     String sync = "sync";
  88     static int nSteps = 0;
  89 
  90     InterruptHangTest (String args[]) {
  91         super(args);
  92     }
  93 
  94     public static void main(String[] args)      throws Exception {
  95         new InterruptHangTest(args).startTests();
  96     }
  97 
  98     /********** event handlers **********/
  99 
 100     public void stepCompleted(StepEvent event) {
 101         synchronized(sync) {
 102             nSteps++;
 103         }
 104         println("Got StepEvent " + nSteps + " at line " +
 105                 event.location().method() + ":" +
 106                 event.location().lineNumber());
 107         if (nSteps == 1) {
 108             timerThread.start();
 109         }
 110     }
 111 
 112     /********** test core **********/
 113 
 114     protected void runTests() throws Exception {
 115         BreakpointEvent bpe = startToMain("InterruptHangTarg");
 116         mainThread = bpe.thread();
 117         EventRequestManager erm = vm().eventRequestManager();
 118 
 119         /*
 120          * Set event requests
 121          */
 122         StepRequest request = erm.createStepRequest(mainThread,
 123                                                     StepRequest.STEP_LINE,
 124                                                     StepRequest.STEP_OVER);
 125         request.enable();
 126 
 127         // Will be started by the step event handler
 128         timerThread = new Thread("test timer") {
 129                 public void run() {
 130                     int mySteps = 0;
 131                     while (true) {
 132                         try {
 133                             Thread.sleep(20000);
 134                             synchronized(sync) {
 135                                 System.out.println("steps = " + nSteps);
 136                                 if (mySteps == nSteps) {
 137                                     // no step for 10 secs
 138                                     failure("failure: Debuggee appears to be hung");
 139                                     vm().exit(-1);
 140                                     break;
 141                                 }
 142                             }
 143                             mySteps = nSteps;
 144                         } catch (InterruptedException ee) {
 145                             break;
 146                         }
 147                     }
 148                 }
 149             };
 150 
 151         /*
 152          * resume the target listening for events
 153          */
 154 
 155         listenUntilVMDisconnect();
 156         timerThread.interrupt();
 157 
 158         /*
 159          * deal with results of test
 160          * if anything has called failure("foo") testFailed will be true
 161          */
 162         if (!testFailed) {
 163             println("InterruptHangTest: passed");
 164         } else {
 165             throw new Exception("InterruptHangTest: failed");
 166         }
 167     }
 168 }