Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-1215887

ThreadDeath can't always stop threads

XMLWordPrintable

    • 1.0beta
    • sparc
    • solaris_2.4
    • Not verified

      When stopping threads we currently rely on threads responding to a ThreadDeath
      exception posted asynchronously against the threads to be stopped. However,
      the ThreadDeath mechanism is parasitic on the exception mechanism. In the
      interpreter, the only VM instructions that check for exceptions are those that might
      have caused an exception to be raised synchronously (e.g. field access, method call
      or divide). VM instructions that can't raise an exception don't even look. When a
      ThreadDeath is posted, the nearest instruction that looks for exceptions will process
      it and the thread will exit.

      Unfortunately, it is possible to write long or infinite computations that contain no
      instructions that can synchronously raise exceptions. These computations will never
      check for ThreadDeath posted against them. The simplest example of this is a
      while-forever loop with an empty body. Such a thread is currently impossible to
      kill, which is a security hole.

      A sufficient guard against this problem is to add a check for exceptions on every
      backwards branch. Note that it is not sufficient to do this for a subset of the
      branch instructions and compile loops using those, or to add a new "check
      exceptions" instruction that would live in every loop, because we also need to
      protect against code generated by evil compilers that use different instructions.

      An example that exhibits the problem:

      class Runner extends Thread {

          public int tick = 1;

          public void run() {
      try {
      while (tick < 1000000) {
      // System.err.println("Hello " + tick);
      tick++;
      }
      } catch (ThreadDeath exc) {
      System.err.println("Runner Dying");
      }
          }
      }

      class Race {
          public static void main(String args[]) {
      Runner runner = new Runner();
      runner.setPriority(2);
      runner.start();
      Thread.currentThread().sleep(100);
      runner.stop();
      System.err.println("Delivered stop to runner 1");
          }
      }

      In the current runtime, the Runner will time out and never catch the ThreadDeath
      exception, because its little loop contains no instructions that check for exceptions.
      If the println of "Hello" is commented back in, the method calls it entails will
      check, and the ThreadDeath will be caught.

            tlindholsunw Timothy Lindholm (Inactive)
            tlindholsunw Timothy Lindholm (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: