Skip to content

Commit 395b878

Browse files
authored
Merge pull request #2041 from MarcMil/concurrentqueuereader
Disallow null in QueueReader to handle concurrency correctly
2 parents bda7b9b + 50b0479 commit 395b878

13 files changed

+51
-17
lines changed

src/main/java/soot/MethodToContexts.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ public MethodToContexts(Iterator<MethodOrMethodContext> it) {
5555
public void add(Iterator<MethodOrMethodContext> it) {
5656
while (it.hasNext()) {
5757
MethodOrMethodContext momc = it.next();
58-
add(momc);
58+
if (momc != null) {
59+
add(momc);
60+
}
5961
}
6062
}
6163

src/main/java/soot/jimple/spark/builder/ContextInsensitiveBuilder.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,14 @@ public void build() {
104104
}
105105
while (callEdges.hasNext()) {
106106
Edge e = callEdges.next();
107+
if (e == null) {
108+
continue;
109+
}
107110
if (!e.isInvalid()) {
108111
if (e.tgt().isConcrete() || e.tgt().isNative()) {
109-
MethodPAG mpag = MethodPAG.v(pag, e.tgt());
110-
mpag.build();
111-
mpag.addToPAG(null);
112+
MethodPAG mpag = MethodPAG.v(pag, e.tgt());
113+
mpag.build();
114+
mpag.addToPAG(null);
112115
}
113116
pag.addCallTarget(e);
114117
}

src/main/java/soot/jimple/spark/geom/geomPA/GeomPointsTo.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,11 @@ private void preprocess() {
359359
CallGraph soot_callgraph = Scene.v().getCallGraph();
360360

361361
while (smList.hasNext()) {
362-
final SootMethod func = smList.next().method();
362+
MethodOrMethodContext n = smList.next();
363+
if (n == null) {
364+
continue;
365+
}
366+
final SootMethod func = n.method();
363367
func2int.put(func, id);
364368
int2func.put(id, func);
365369

@@ -385,7 +389,7 @@ private void preprocess() {
385389
QueueReader<Edge> edgeList = Scene.v().getCallGraph().listener();
386390
while (edgeList.hasNext()) {
387391
Edge edge = edgeList.next();
388-
if (edge.isClinit()) {
392+
if (edge == null || edge.isClinit()) {
389393
continue;
390394
}
391395

src/main/java/soot/jimple/spark/internal/TypeManager.java

+3
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ final public BitVector get(Type type) {
115115
final Scene sc = Scene.v();
116116
while (allocNodeListener.hasNext()) {
117117
AllocNode n = allocNodeListener.next();
118+
if (n == null) {
119+
continue;
120+
}
118121
Type nt = n.getType();
119122
Iterable<Type> types;
120123
if (nt instanceof NullType || nt instanceof AnySubType) {

src/main/java/soot/jimple/spark/solver/OnFlyCallGraph.java

+6
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ private void processReachables() {
111111
reachableMethods.update();
112112
while (reachablesReader.hasNext()) {
113113
MethodOrMethodContext m = reachablesReader.next();
114+
if (m == null) {
115+
continue;
116+
}
114117
MethodPAG mpag = MethodPAG.v(pag, m.method());
115118
try {
116119
mpag.build();
@@ -129,6 +132,9 @@ private void processReachables() {
129132
private void processCallEdges() {
130133
while (callEdges.hasNext()) {
131134
Edge e = callEdges.next();
135+
if (e == null) {
136+
continue;
137+
}
132138
MethodPAG amp = MethodPAG.v(pag, e.tgt());
133139
amp.build();
134140
amp.addToPAG(e.tgtCtxt());

src/main/java/soot/jimple/toolkits/callgraph/CallGraph.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.LinkedHashMap;
3030
import java.util.LinkedHashSet;
3131
import java.util.Map;
32+
import java.util.NoSuchElementException;
3233
import java.util.Set;
3334

3435
import soot.Kind;
@@ -99,7 +100,7 @@ public boolean removeAllEdgesOutOf(Unit u) {
99100
Set<Edge> edgesToRemove = new HashSet<>();
100101
for (QueueReader<Edge> edgeRdr = listener(); edgeRdr.hasNext();) {
101102
Edge e = edgeRdr.next();
102-
if (e.srcUnit() == u) {
103+
if (e != null && e.srcUnit() == u) {
103104
e.remove();
104105
removeEdge(e, false);
105106
edgesToRemove.add(e);
@@ -395,7 +396,9 @@ public String toString() {
395396
StringBuilder out = new StringBuilder();
396397
for (QueueReader<Edge> reader = listener(); reader.hasNext();) {
397398
Edge e = reader.next();
398-
out.append(e.toString()).append('\n');
399+
if (e != null) {
400+
out.append(e.toString()).append('\n');
401+
}
399402
}
400403
return out.toString();
401404
}

src/main/java/soot/jimple/toolkits/callgraph/CallGraphBuilder.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public void build() {
111111
break;
112112
}
113113
final MethodOrMethodContext momc = worklist.next();
114-
if (!process(momc)) {
114+
if (momc != null && !process(momc)) {
115115
break;
116116
}
117117
}

src/main/java/soot/jimple/toolkits/callgraph/Filter.java

+3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ public Iterator<Edge> wrap(Iterator<Edge> source) {
4848
private void advance() {
4949
while (source.hasNext()) {
5050
next = source.next();
51+
if (next == null) {
52+
continue;
53+
}
5154
if (pred.want(next)) {
5255
return;
5356
}

src/main/java/soot/jimple/toolkits/callgraph/OnFlyCallGraphBuilder.java

+3
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,9 @@ public void processReachables() {
279279
}
280280
}
281281
MethodOrMethodContext momc = worklist.next();
282+
if (momc == null) {
283+
continue;
284+
}
282285
SootMethod m = momc.method();
283286
if (appOnly && !m.getDeclaringClass().isApplicationClass()) {
284287
continue;

src/main/java/soot/jimple/toolkits/callgraph/ReachableMethods.java

+4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.util.Collection;
2626
import java.util.HashSet;
2727
import java.util.Iterator;
28+
import java.util.NoSuchElementException;
2829
import java.util.Set;
2930

3031
import soot.MethodOrMethodContext;
@@ -89,6 +90,9 @@ public void update() {
8990
}
9091
while (unprocessedMethods.hasNext()) {
9192
MethodOrMethodContext m = unprocessedMethods.next();
93+
if (m == null) {
94+
continue;
95+
}
9296
Iterator<Edge> targets = cg.edgesOutOf(m);
9397
if (filter != null) {
9498
targets = filter.wrap(targets);

src/main/java/soot/jimple/toolkits/callgraph/SlowCallGraph.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@ public String toString() {
134134
StringBuilder out = new StringBuilder();
135135
for (QueueReader<Edge> rdr = listener(); rdr.hasNext();) {
136136
Edge e = rdr.next();
137-
out.append(e.toString()).append('\n');
137+
if (e != null) {
138+
out.append(e.toString()).append('\n');
139+
}
138140
}
139141
return out.toString();
140142
}

src/main/java/soot/util/queue/ChunkedQueue.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
@SuppressWarnings("unchecked")
3434
public class ChunkedQueue<E> {
3535

36-
protected static final Object NULL_CONST = new Object();
3736
protected static final Object DELETED_CONST = new Object();
3837

3938
protected static final int LENGTH = 60;
@@ -48,7 +47,7 @@ public ChunkedQueue() {
4847
/** Add an object to the queue. */
4948
public void add(E o) {
5049
if (o == null) {
51-
o = (E) NULL_CONST;
50+
throw new IllegalArgumentException("Null is not allowed");
5251
}
5352
if (index == LENGTH - 1) {
5453
Object[] temp = new Object[LENGTH];

src/main/java/soot/util/queue/QueueReader.java

+7-5
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
* been read by all the QueueReader's are kept. A QueueReader only receives the Object's added to the queue <b>after</b> the
3636
* QueueReader was created.
3737
*
38+
* This QueueReader does <emph>not</emph> accept <code>null</code> values.
3839
* @author Ondrej Lhotak
3940
*/
4041
public class QueueReader<E> implements java.util.Iterator<E> {
@@ -54,19 +55,20 @@ public E next() {
5455
Object ret = null;
5556
do {
5657
if (q[index] == null) {
57-
throw new NoSuchElementException();
58+
//this is the case when someone concurrently invalidates
59+
//the rest of the elements
60+
return null;
5861
}
5962
if (index == q.length - 1) {
6063
q = (E[]) q[index];
6164
index = 0;
6265
if (q[index] == null) {
63-
throw new NoSuchElementException();
66+
//this is the case when someone concurrently invalidates
67+
//the rest of the elements
68+
return null;
6469
}
6570
}
6671
ret = q[index];
67-
if (ret == ChunkedQueue.NULL_CONST) {
68-
ret = null;
69-
}
7072
index++;
7173
} while (skip(ret));
7274
return (E) ret;

0 commit comments

Comments
 (0)