[Soot-list] CuncurrentModificationException

Eric Bodden eric.bodden at mail.mcgill.ca
Wed Aug 20 09:38:06 EDT 2008


Soto calls a BodyTransformer in a loop, executing it for each body
(each one that has a body, that is) of each application class. You
modify the list of methods *while* this iteration happens. This is
forbidden.

The solution is to use a SceneTransformer instead, stick it in the
wjtp pack, and then do this iteration manually in your code. Make sure
that when you iterate over a class you actually iterate over a *copy*
of the list of the methods in that class so that you can modify the
actual list of methods concurrently.

Eric

2008/8/20 Bashar Al Rawi <brawi at umich.edu>:
> public class Instrumenter extends BodyTransformer {
>
>     private boolean isObjectInstrumented = false;
>     private Set<SootClass> selfRefObjSet = new HashSet<SootClass>();
>     private static Instrumenter instance = new Instrumenter();
>
>     private Instrumenter() {
>     }
>
>     public static Instrumenter v() {
>         return instance;
>     }
>
> private SootClass getTopNonLibClass(SootClass s){
>         if(!selfRefObjSet.contains(s))
>             selfRefObjSet.add(s);
>         System.out.println("CURRENT CLASS: " + s);
>         if(s.getSuperclass().isLibraryClass())
>             return s;
>         return getTopNonLibClass(s.getSuperclass());
>     }
>
>     private void instrumentSelfRef(SootClass sc) {
>         if (implementsSelfRef(sc))
>             return;
>         SootClass c = getTopNonLibClass(sc);
>         System.out.println("Top Non-Lib Class = " + c);
>         SootField objVar = new SootField("thisRef", RefType
>                 .v("tracer.util.ObjVar"), Modifier.PUBLIC);
>         c.addField(objVar);
>         SootClass selfRefInterface = null;
>         if (!Scene.v().containsClass("tracer.util.SelfRef")) {
>             selfRefInterface = new SootClass("tracer.util.SelfRef",
>                     Modifier.PUBLIC | Modifier.INTERFACE);
>         } else {
>             selfRefInterface =
> Scene.v().getSootClass("tracer.util.SelfRef");
>         }
>         assert selfRefInterface.isInterface();
>         c.addInterface(selfRefInterface);
>         SootMethod m = new SootMethod("getSelfRef",
>                 Arrays.asList(VoidType.v()),
> RefType.v("tracer.util.ObjVar"),
>                 Modifier.PUBLIC);
>         c.addMethod(m);   //
> -------------------------------------------------------> If I remove this
> statement, everything works fine
>
>     }
>     private void instrumentClasses(){
>         Iterator it = Scene.v().getApplicationClasses().snapshotIterator();
>         while(it.hasNext()){
>
>             SootClass c = (SootClass) it.next();
>             instrumentSelfRef(c);
>             System.out.println(c.getMethods());
>         }
>     }
>     protected void internalTransform(Body body, String pn, Map map) {
>         System.out.println(Scene.v().getApplicationClasses());
>         if(!isObjectInstrumented){
>             isObjectInstrumented = true;
>             instrumentClasses();
>         }
>
>
>         instrumentStmt(body);
>
>     }
> }
>
>
> Here is the output I got:
>
> Transforming tracer.benchmarks.Toy1...
> [tracer.benchmarks.Toy1, tracer.benchmarks.MyThread]
> CURRENT CLASS: tracer.benchmarks.Toy1
> Top Non-Lib Class = tracer.benchmarks.Toy1
> [<tracer.benchmarks.Toy1: void <init>()>, <tracer.benchmarks.Toy1: void
> main(java.lang.String[])>, <tracer.benchmarks.Toy1: tracer.util.ObjVar
> getSelfRef(void)>]
> CURRENT CLASS: tracer.benchmarks.MyThread
> Top Non-Lib Class = tracer.benchmarks.MyThread
> [<tracer.benchmarks.MyThread: void <init>()>, <tracer.benchmarks.MyThread:
> void run()>, <tracer.benchmarks.MyThread: int getX()>,
> <tracer.benchmarks.MyThread: tracer.util.ObjVar getSelfRef(void)>]
> method: <init>
> r0 := @this: tracer.benchmarks.Toy1
> Identity: r0 := @this: tracer.benchmarks.Toy1
> specialinvoke r0.<java.lang.Object: void <init>()>()
> return
> Exception in thread "main" java.util.ConcurrentModificationException
>     at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
>     at java.util.AbstractList$Itr.next(Unknown Source)
>     at soot.PackManager.runBodyPacks(PackManager.java:735)
>     at soot.PackManager.runBodyPacks(PackManager.java:451)
>     at soot.PackManager.runBodyPacks(PackManager.java:370)
>     at soot.PackManager.runPacks(PackManager.java:347)
>     at soot.Main.run(Main.java:203)
>     at soot.Main.main(Main.java:146)
>     at tracer.instrument.Instrumenter.main(Instrumenter.java:675)
>
>
> Thanks a lot in advance.
>
>
>
> On Tue, Aug 19, 2008 at 11:21 PM, Richard L. Halpert
> <richardlhalpert at gmail.com> wrote:
>>
>> Your explanation of the problem is rather vague.  Please send code.
>>
>> -Richard
>>
>> On Tue, Aug 19, 2008 at 5:31 PM, Bashar Al Rawi <brawi at umich.edu> wrote:
>>>
>>> Hi,
>>>
>>> I am trying to add modify a class file by overwriting the
>>> internalTransform method. However, whenever I add a new method to the class,
>>> I get java.util.ConcurrentModificationException. I tried using
>>> snapshotIterator, but its not working. Can you please tell me wat's
>>> happening?
>>>
>>> Thanks
>>>
>>> --
>>> Bashar
>>>
>>>
>>> _______________________________________________
>>> Soot-list mailing list
>>> Soot-list at sable.mcgill.ca
>>> http://mailman.cs.mcgill.ca/mailman/listinfo/soot-list
>>>
>>
>
>
>
> --
> Bashar
>
> _______________________________________________
> Soot-list mailing list
> Soot-list at sable.mcgill.ca
> http://mailman.cs.mcgill.ca/mailman/listinfo/soot-list
>
>



-- 
Eric Bodden
Sable Research Group
McGill University, Montréal, Canada


More information about the Soot-list mailing list