Does "Thread.stop" do what is says it does?

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Does "Thread.stop" do what is says it does?

Dawid Kurzyniec
The javadoc of Thread.stop says:

     * It is permitted to stop a thread that has not yet been started.
     * If the thread is eventually started, it immediately terminates.

However, the first statement of Thread.stop is:

            if (!this.isAlive()) return;

And isAlive javadoc says:

     * Tests if this thread is alive. A thread is alive if it has
     * been started and has not yet died.

This seems to imply that stop is a no-op on a thread that has not yet
started, and I can't see why the thread would be terminated as soon as
it starts. So what's the deal here?


BTW:

I know that Thread.stop is deprecated and pure evil, I realize the risks
of getting inconsistent data by abruptly releasing locks, but I think
that in the system I am writing, using Thread.stop is necessary and the
risks are manageable. I am developing a multi-user middleware platform
(a distributed service container) which runs potentially untrusted code
in isolated sandboxes. Sometimes, though, "friend" services are allowed
to break the isolation barriers and share data, so the "Isolates" API is
not applicable. Instead, we implement sandboxing via separate class
loaders, strict confinement, and security policies.

For the sake of this discussion, let's assume that I am implementing an
applet container that can host multiple applets at a time. Let's say I
loaded an applet that became unresponsive and I want to unload it
anyway. I first ask it nicely to leave, wait a while, then interrupt all
its threads, wait a while, then stop all threads, wait a while, then
finally blacklist all remaining threads, set their priorities to minimum
and revoke all their security privileges. Stopping seems to be fairly
safe, since those applets don't really share any objects, so whatever
gets messed up as a result of abrupt stopping becomes a garbage anyway.
And, even if they somehow manage to lock a shared system object (which
is generally prevented by security policies, e.g. they cannot write to
standard output), the system is at a deadlock anyway if I don't stop
those bastards :)

Sure, really evil services can escape the axe by catching ThreadDeath.
Little I can do about that. But here I am trying to guard against poorly
written or buggy ones (e.g. looping infinitely, in which case merely
interrupting them won't suffice) rather than malicious ones. (The latter
case is dealt with using code source certificates etc.)

Regards,
Dawid

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Does "Thread.stop" do what is says it does?

Dawid Kurzyniec
Dawid Kurzyniec wrote:

> The javadoc of Thread.stop says:
>
>     * It is permitted to stop a thread that has not yet been started.
>     * If the thread is eventually started, it immediately terminates.
>
> However, the first statement of Thread.stop is:
>
>            if (!this.isAlive()) return;
>
> And isAlive javadoc says:
>
>     * Tests if this thread is alive. A thread is alive if it has
>     * been started and has not yet died.
>
> This seems to imply that stop is a no-op on a thread that has not yet
> started, and I can't see why the thread would be terminated as soon as
> it starts. So what's the deal here?

Replying to myself: the observed behavior seems to be that stop followed
by start does not cause immediate thread termination, so I guess I
report it here as a bug. (I guess it should be "if (this.getState() ==
TERMINATED) return;" or something equivalent).

Regards,
Dawid

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Does "Thread.stop" do what is says it does?

Miles Sabin
In reply to this post by Dawid Kurzyniec
Dawid Kurzyniec wrote,
> Sometimes, though, "friend" services are allowed to break the
> isolation barriers and share data, so the "Isolates" API is not
> applicable. Instead, we implement sandboxing via separate class
> loaders, strict confinement, and security policies.

I'm not going to comment on the ethics of using Thread.stop, but I can't
let this pass ...

Isolates really, really, really are exactly what you want. Yes, you'll
most likely have to use message passing to achieve effects equivalent
to shared state. But this will always be possible, and assuming a
reasonably well behaved and efficient implementation of the Link API a
message passing alternative shouldn't be problematic from a performance
point of view.

Sandboxing via classloader partitioning and security policies are the
best we currently have, but they can't prevent interference due to
buggy or malicious code, and they can't provide resource managment or
revocation in any particularly general or reliable way ... Thread.stop
is just the tip of the iceberg.

"Partial isolation" would be lovely, but to do it properly (or even
approximate it) would require so many drastic changes to Java's type
system and overall semantics that I'm sorry to say we'll never see it.

Cheers,


Miles
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Does "Thread.stop" do what is says it does?

David Holmes
In reply to this post by Dawid Kurzyniec
Dawid,

> Replying to myself: the observed behavior seems to be that stop followed
> by start does not cause immediate thread termination, so I guess I
> report it here as a bug. (I guess it should be "if (this.getState() ==
> TERMINATED) return;" or something equivalent).

There is a lot of history here and numerous bugs concerning the incorrect
behaviour of "still born" threads - ones which have been stopped before they
started. Back in 1.1 it worked as advertised, but there was a different bug
whereby once stop() had been called then isAlive() returned false even
though the thread was not terminated. In 1.2 if I recall correctly they
fixed the isAlive problem, broke the still-born behaviour and deprecated the
stop method. So thereafter any bug reports concerning this were flagged as
"will not fix as it concerns a deprecated method". Not sure what bugs are
still present in the bug parade.

In short you cannot rely on Thread.stop doing anything per its documentation
these days.

David Holmes

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

RE: Does "Thread.stop" do what is says it does?

Ian Griffiths
It seems to me that this discussion still leaves unanswered the central
question:

- How can we stop a thread that has got out of control (infinite looping
or other anti-social behavior)?

I have the case with an application that we've written that runs code
provided by different departments (like applets) in separate classloaders.

As the different departments have varying IT, Java and testing skills,
we occasionally have this case. It is very annoying as the only solution
seems to be to stop a system running hundreds of users if the "Applet"
refuses to stop of its own accord.

I think all people in this situation are waiting impatiently for
Isolates. But is there any thing we can do until they come?

Ian

-----Original Message-----
From: "David Holmes" <[hidden email]>
To: "Dawid Kurzyniec" <[hidden email]>,
<[hidden email]>
Cc:
Date: Fri, 5 Aug 2005 11:39:09 +1000
Subject: ***SPAM*** Score/Req: 8.0/7.7 - RE: [concurrency-interest] Does
"Thread.stop" do what is says it does?

> Dawid,
>
> > Replying to myself: the observed behavior seems to be that stop
> followed
> > by start does not cause immediate thread termination, so I guess I
> > report it here as a bug. (I guess it should be "if (this.getState()
> ==
> > TERMINATED) return;" or something equivalent).
>
> There is a lot of history here and numerous bugs concerning the
> incorrect
> behaviour of "still born" threads - ones which have been stopped
> before they
> started. Back in 1.1 it worked as advertised, but there was a
> different bug
> whereby once stop() had been called then isAlive() returned false
> even
> though the thread was not terminated. In 1.2 if I recall correctly
> they
> fixed the isAlive problem, broke the still-born behaviour and
> deprecated the
> stop method. So thereafter any bug reports concerning this were
> flagged as
> "will not fix as it concerns a deprecated method". Not sure what bugs
> are
> still present in the bug parade.
>
> In short you cannot rely on Thread.stop doing anything per its
> documentation
> these days.
>
> David Holmes
>
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Does "Thread.stop" do what is says it does?

Joshua Bloch
Ian,

On 8/5/05, Ian Griffiths <[hidden email]> wrote:
> It seems to me that this discussion still leaves unanswered the central
> question:
>
> - How can we stop a thread that has got out of control (infinite looping
> or other anti-social behavior)?

If you need absolute safety, kill the process (VM).  Nothing else is
guaranteed to work.  Merely using separate classloaders is not
sufficient.  It lowers the odds of a catastrophic failure, but does
not prevent one.  If you're willing to take chances, call Thread.stop
and hope for the best.  In the absence of isolates, I really don't
think there's a lot more to say about the topic.

            Josh

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Does "Thread.stop" do what is says it does?

Dawid Kurzyniec
In reply to this post by Ian Griffiths
Ian Griffiths wrote:

>It seems to me that this discussion still leaves unanswered the central
>question:
>
>- How can we stop a thread that has got out of control (infinite looping
>or other anti-social behavior)?
>  
>
As Josh said, nothing is really foolproof, since a malicious thread can
always catch and ignore ThreadDeath. In fact, some months ago I was
experiencing JVM crashes when simulating such malicious service and
attempts of the system to aggressively get rid of it. But, if it is safe
to assume that the code is not malicious, but that it can be just buggy
(e.g. frequent pattern: try { ... } catch (InterruptedException e) {}),
with careful class loader confinement, I think Thread.stop is the best
solution we have now. Before stopping, it is probably a good idea to
apply the procedure described in CPJ book: ask nicely, then interrupt,
then revoke security privileges and lower priority.

The best solution I can come up with to the problem of Thread.stop being
no-op if the thread has not yet been started, is to check isAlive, and
if false, precede stop() with start() (catching possible exception).
Thread references should be kept in a weak data structure, so that
unreferenced threads are ignored and gc-ed even if they have not yet
started. This way, when we see a non-collected thread that is not alive,
we know that somebody probably holds a reference to it and may be
planning something nasty, so it is safer to defensively start/stop.

Also, a non-trivial problem here is to decide which threads should
actually be terminated, since, in general, the mapping between services
(or sessions) and threads is dynamic. Our system
(http://www.mathcs.emory.edu/dcl/h2o/) permits external remote
invocations of hosted services. When an RMI thread enters the service
code, it becomes subject to termination if the service is destroyed, but
it is no longer so after it exits the service code. When a thread
"attached" to a service spawns a new thread, that new thread should also
be "attached" to the service. Implementing this seems impossible at
first sight, but it can be done with a bit of trickery, intercepting
setPriority() from the thread constructor in a security manager.
Finally, tasks submitted to thread pools by a thread "attached" to a
service should usually also be attached to that service. To achieve
that, we have implemented a thread local delegation mechanism, and a
simple security-extended version of ThreadPoolExecutor, which delegates
context class loader, access control context, and delegatable thread
locals from the submitter to the task. As long as all "shared" thread
pools are instances of this class, the service-to-threads association is
correctly preserved.

In addition to service-to-threads association, we needed
session-to-threads association: when the user session is terminated, all
threads associated with that session should be terminated. This can be
implemented in an analogous way as service-to-threads association.

Regards,
Dawid

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Does "Thread.stop" do what is says it does?

Dawid Kurzyniec
In reply to this post by Miles Sabin
Miles Sabin wrote:

>Dawid Kurzyniec wrote,
>  
>
>>Sometimes, though, "friend" services are allowed to break the
>>isolation barriers and share data, so the "Isolates" API is not
>>applicable. Instead, we implement sandboxing via separate class
>>loaders, strict confinement, and security policies.
>>    
>>
>
>I'm not going to comment on the ethics of using Thread.stop, but I can't
>let this pass ...
>
>Isolates really, really, really are exactly what you want. Yes, you'll
>most likely have to use message passing to achieve effects equivalent
>to shared state. But this will always be possible, and assuming a
>reasonably well behaved and efficient implementation of the Link API a
>message passing alternative shouldn't be problematic from a performance
>point of view.
>
>Sandboxing via classloader partitioning and security policies are the
>best we currently have, but they can't prevent interference due to
>buggy or malicious code, and they can't provide resource managment or
>revocation in any particularly general or reliable way ... Thread.stop
>is just the tip of the iceberg.
>
>  
>
When isolates appear, we will definitely give them a second look - at
least, they may allow us to implement a configurable hierarchies of
isolation levels (process, isolate, class loader, shared). But our
system (http://www.mathcs.emory.edu/dcl/h2o/) is not an applet
container, or a servlet engine - it is a distributed computing and
resource sharing platform. Services (which we call pluglets) are pieces
of distributed applications, and they are in fact expected to
communicate. If they happen to be loaded into the same address space, it
is important that they can share data directly. In other words, in our
typical applications, communication performance requirements usually
outweight isolation requirements. The container owner provides a
security policy that prevents untrusted pluglets from loading; we can
thus expect certain level of cooperation from loaded pluglets, we just
need to shield the system from buggy ones. Given all that, I find the
abstraction of isolates too, well, isolating, to be used as a default in
our system. Nonetheless, as I said, it may be very interesting to allow
hierarchical levels of isolation in the future.

Regards,
Dawid

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Does "Thread.stop" do what is says it does?

Miles Sabin
Dawid Kurzyniec wrote,

> When isolates appear, we will definitely give them a second look - at
> least, they may allow us to implement a configurable hierarchies of
> isolation levels (process, isolate, class loader, shared). But our
> system (http://www.mathcs.emory.edu/dcl/h2o/) is not an applet
> container, or a servlet engine - it is a distributed computing and
> resource sharing platform. Services (which we call pluglets) are
> pieces of distributed applications, and they are in fact expected to
> communicate. If they happen to be loaded into the same address space,
> it is important that they can share data directly. In other words, in
> our typical applications, communication performance requirements
> usually outweight isolation requirements.

Understood, not the least because, as far as my day job is concerned,
this is precisely my situation too.

Given an application which is already structured in such a way that
inter-process and inter-host interaction is accommodated, the mapping
to Isolates and Links should be a relatively painless, even pleasant,
experience (if that's not the case, comments to isolate-interest@
altair.cs.oswego.edu ASAP would be much appreciated).

The rest is down to quality of implementation. I'm hopeful, but the best
I can do is report that my early multi-process prototype implementation
of JSR-121 (conformant at the time, but not in any way tuned) performed
adequately on a variety of typical distributed computing style
benchmarks. I'd expect that an industrial strength implementation would
do much better. Which is not to say that I'd recommend Isolates and
Links for emulating fine-grained CSP- or pi-style computational models,
but anything somewhat coarser than that should get along with them just
fine. In extreme cases, Isolates can share state via memory mapped
files using Links for coordination.

> Given all that, I find the abstraction of isolates too, well,
> isolating, to be used as a default in our system.

Odd perhaps, but I find the opposite to be the case. Treating everything
as remote, even when it might be local is a strangely liberating
experience ;-)

Cheers,


Miles
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Does "Thread.stop" do what is says it does?

Gregg Wonderly-2


Miles Sabin wrote:
>>Given all that, I find the abstraction of isolates too, well,
>>isolating, to be used as a default in our system.
>
> Odd perhaps, but I find the opposite to be the case. Treating everything
> as remote, even when it might be local is a strangely liberating
> experience ;-)

The Jini platform provides a rather liberating mechanism through the use of the RMI programming model to drive you to
think in this direction.  When you finally decide that things should be separated, it's amazing how fast you can find
things that can be separated from the cohesive forces that single JVMs put on your architecture...

Gregg Wonderly
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest