undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 5086470 6358247
|
||||
* @summary Basic Test for ThreadMXBean.dumpAllThreads(false, true)
|
||||
* and getThreadInfo of customized JSR-166 synchronizers.
|
||||
* @author Mandy Chung
|
||||
*
|
||||
* @build Barrier
|
||||
* @build ThreadDump
|
||||
* @run main/othervm MyOwnSynchronizer
|
||||
*/
|
||||
|
||||
import java.lang.management.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.io.*;
|
||||
|
||||
public class MyOwnSynchronizer {
|
||||
static ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
|
||||
static Mutex mutex = new Mutex();
|
||||
static MyThread thread = new MyThread();
|
||||
public static void main(String[] argv) throws Exception {
|
||||
if (!mbean.isSynchronizerUsageSupported()) {
|
||||
System.out.println("Monitoring of synchronizer usage not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
|
||||
// wait until myThread acquires mutex
|
||||
while (!mutex.isLocked()) {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
ThreadDump.threadDump();
|
||||
// Test dumpAllThreads with locked synchronizers
|
||||
ThreadInfo[] tinfos = mbean.dumpAllThreads(false, true);
|
||||
for (ThreadInfo ti : tinfos) {
|
||||
MonitorInfo[] monitors = ti.getLockedMonitors();
|
||||
if (monitors.length != 0) {
|
||||
throw new RuntimeException("Name: " + ti.getThreadName() +
|
||||
" has non-empty locked monitors = " + monitors.length);
|
||||
}
|
||||
LockInfo[] syncs = ti.getLockedSynchronizers();
|
||||
if (ti.getThreadId() == thread.getId()) {
|
||||
thread.checkLockedSyncs(ti, syncs);
|
||||
}
|
||||
}
|
||||
|
||||
// Test getThreadInfo with locked synchronizers
|
||||
tinfos = mbean.getThreadInfo(new long[] {thread.getId()}, false, true);
|
||||
if (tinfos.length != 1) {
|
||||
throw new RuntimeException("getThreadInfo() returns " +
|
||||
tinfos.length + " ThreadInfo objects. Expected 0.");
|
||||
}
|
||||
ThreadInfo ti = tinfos[0];
|
||||
if (ti.getLockedMonitors().length != 0) {
|
||||
throw new RuntimeException("Name: " + ti.getThreadName() +
|
||||
" has non-empty locked monitors = " +
|
||||
ti.getLockedMonitors().length);
|
||||
}
|
||||
thread.checkLockedSyncs(ti, ti.getLockedSynchronizers());
|
||||
|
||||
System.out.println("Test passed");
|
||||
}
|
||||
|
||||
static class Mutex implements Lock, java.io.Serializable {
|
||||
|
||||
// Our internal helper class
|
||||
class Sync extends AbstractQueuedSynchronizer {
|
||||
// Report whether in locked state
|
||||
protected boolean isHeldExclusively() {
|
||||
return getState() == 1;
|
||||
}
|
||||
|
||||
// Acquire the lock if state is zero
|
||||
public boolean tryAcquire(int acquires) {
|
||||
assert acquires == 1; // Otherwise unused
|
||||
if (compareAndSetState(0, 1)) {
|
||||
setExclusiveOwnerThread(Thread.currentThread());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Release the lock by setting state to zero
|
||||
protected boolean tryRelease(int releases) {
|
||||
assert releases == 1; // Otherwise unused
|
||||
if (getState() == 0) throw new IllegalMonitorStateException();
|
||||
setExclusiveOwnerThread(null);
|
||||
setState(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Provide a Condition
|
||||
Condition newCondition() { return new ConditionObject(); }
|
||||
|
||||
// Deserialize properly
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
s.defaultReadObject();
|
||||
setState(0); // reset to unlocked state
|
||||
}
|
||||
}
|
||||
|
||||
// The sync object does all the hard work. We just forward to it.
|
||||
private final Sync sync = new Sync();
|
||||
|
||||
public void lock() { sync.acquire(1); }
|
||||
public boolean tryLock() { return sync.tryAcquire(1); }
|
||||
public void unlock() { sync.release(1); }
|
||||
public Condition newCondition() { return sync.newCondition(); }
|
||||
public boolean isLocked() { return sync.isHeldExclusively(); }
|
||||
public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); }
|
||||
public void lockInterruptibly() throws InterruptedException {
|
||||
sync.acquireInterruptibly(1);
|
||||
}
|
||||
public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
|
||||
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
|
||||
}
|
||||
|
||||
public AbstractOwnableSynchronizer getSync() { return sync; }
|
||||
}
|
||||
|
||||
static class MyThread extends Thread {
|
||||
public MyThread() {
|
||||
super("MyThread");
|
||||
}
|
||||
public void run() {
|
||||
mutex.lock();
|
||||
Object o = new Object();
|
||||
synchronized(o) {
|
||||
try {
|
||||
o.wait();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
int OWNED_SYNCS = 1;
|
||||
void checkLockedSyncs(ThreadInfo info, LockInfo[] syncs) {
|
||||
if (!getName().equals(info.getThreadName())) {
|
||||
throw new RuntimeException("Name: " + info.getThreadName() +
|
||||
" not matched. Expected: " + getName());
|
||||
}
|
||||
|
||||
if (syncs.length != OWNED_SYNCS) {
|
||||
throw new RuntimeException("Number of locked syncs = " +
|
||||
syncs.length +
|
||||
" not matched. Expected: " + OWNED_SYNCS);
|
||||
}
|
||||
AbstractOwnableSynchronizer s = mutex.getSync();
|
||||
String lockName = s.getClass().getName();
|
||||
int hcode = System.identityHashCode(s);
|
||||
if (!lockName.equals(syncs[0].getClassName())) {
|
||||
throw new RuntimeException("LockInfo : " + syncs[0] +
|
||||
" class name not matched. Expected: " + lockName);
|
||||
}
|
||||
if (hcode != syncs[0].getIdentityHashCode()) {
|
||||
throw new RuntimeException("LockInfo: " + syncs[0] +
|
||||
" IdentityHashCode not matched. Expected: " + hcode);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue