Repository: soot-oss/soot

Issue #243: RuntimeException Local not in Chain
Created: 2014-08-19T12:00:40Z
This error pops up when trying to do a infoflow analysis first and then using soot afterwards (see code).
When I move the InfoflowResults res = app.runInfoflow() to the second position right after Scene.v().runNecessaryClasses(); then the error doesn't pops up and it seems that everything works as desired.
//Do Infoflow analysis
SetupApplication app = new SetupApplication
            ("/Users/neji/Documents/Uni-Stuff/Master-Thesis/android-platforms",
             "/Users/neji/Desktop/AndroidSpecific_DirectLeak1.apk");
app.calculateSourcesSinksEntrypoints("/Users/neji/Documents/Uni-Stuff/Master-      
                Thesis/FlowDroid/SourcesAndSinks.txt");

app.setComputeResultPaths(true);
app.setTaintWrapper(new EasyTaintWrapper("/Users/neji/Documents/Uni-Stuff/Master-
               Thesis/FlowDroid/EasyTaintWrapperSource.txt"));
app.setEnableImplicitFlows(true);

InfoflowResults res = app.runInfoflow();  

soot.G.reset();

Options.v().set_src_prec(Options.src_prec_apk);
        Options.v().set_process_dir(Collections.singletonList("/Users/neji/Desktop/AndroidSpecific_DirectLeak1.apk"));
Options.v().set_android_jars("/Users/neji/Documents/Uni-Stuff/Master-Thesis/android-platforms");
Options.v().set_whole_program(true);
Options.v().set_allow_phantom_refs(true);
Options.v().set_output_format(Options.output_format_class);
Options.v().setPhaseOption("cg.spark", "on");

Scene.v().loadNecessaryClasses();

// ------->   InfoflowResults res = app.runInfoflow();   < --------------

SootMethod entryPoint = app.getEntryPointCreator().createDummyMain();
Options.v().set_main_class(entryPoint.getSignature());

Scene.v().setEntryPoints(Collections.singletonList(entryPoint));

PackManager.v().runPacks();
CallGraph cg = Scene.v().getCallGraph();
[...]   
Edit:
Here is the Stacktrace:
Exception in thread "main" java.lang.RuntimeException: Local not in chain : $r0 in <dummyMainClass: void dummyMainMethod()>
    at soot.Body.validateLocal(Body.java:279)
    at soot.Body.validateLocals(Body.java:267)
    at soot.Body.validate(Body.java:231)
    at soot.jimple.JimpleBody.validate(JimpleBody.java:71)
    at soot.baf.BafBody.<init>(BafBody.java:66)
    at soot.baf.Baf.newBody(Baf.java:560)
    at soot.PackManager.convertJimpleBodyToBaf(PackManager.java:956)
    at soot.PackManager.runBodyPacks(PackManager.java:916)
    at soot.PackManager.runBodyPacks(PackManager.java:584)
    at soot.PackManager.runBodyPacks(PackManager.java:487)
    at soot.PackManager.runPacksNormally(PackManager.java:464)
    at soot.PackManager.runPacks(PackManager.java:388)
    at test.main(test.java:62)

Duplicate issue #252: Bug in Soot indicating that a var has different types!
Created: 2014-08-29T05:42:01Z
I have the following issue with the attached code which is supposed to run flowdroid and produce the CFG of the apk..For most of the apps, I get an exception indicating that one of the values has two types, resulting from line: PackManager.v().runPacks();
Quick fix is deeply appreciated!
Thank you,
Modhi

code snippets:
String apk = "D:/APKs/xxxx.apk";
SetupApplication app = new SetupApplication("D:/AndroidADT/adt-bundle-windows-x86_64-20131030/sdk/platforms",apk);
try {
app.calculateSourcesSinksEntrypoints("D:/FlowDroid/SourcesAndSinks.txt");
app.printSinks();
ResultsAvailableHandler rah = new ResAvailable();
InfoflowResults ir = new InfoflowResults();
ir = app.runInfoflow(rah);
System.out.println("FlowDroid Results:");
System.in.read();
if(ir != null)
ir.printResults(); // here sometimes ir is null
System.out.println("FlowDroid Results ends..");
System.in.read();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
soot.G.reset();
Options.v().set_src_prec(Options.src_prec_apk);
Options.v().set_process_dir(Collections.singletonList(apk));
Options.v().set_android_jars("D:/AndroidADT/adt-bundle-windows-x86_64-20131030/sdk/platforms");
Options.v().set_whole_program(true);
Options.v().set_allow_phantom_refs(true);
Options.v().set_output_format(Options.output_format_none);
Options.v().setPhaseOption("cg.spark", "on");
Scene.v().loadNecessaryClasses();
SootMethod entryPoint = app.getEntryPointCreator().createDummyMain();
Options.v().set_main_class(entryPoint.getSignature());
Scene.v().setEntryPoints(Collections.singletonList(entryPoint));
System.out.println(entryPoint.getActiveBody());
PackManager.v().runPacks(); // the exception always refers to this line
the exception I got:
Exception in thread "main" java.lang.RuntimeException: Value $r0 of type de.underflow.calc.CalculatorPreferenceActivity previously had type android.os.Bundle
at soot.jimple.spark.pag.PAG.makeLocalVarNode(PAG.java:543)
at soot.jimple.spark.builder.MethodNodeFactory.caseLocal(MethodNodeFactory.java:219)
at soot.jimple.internal.JimpleLocal.apply(JimpleLocal.java:136)
at soot.jimple.spark.builder.MethodNodeFactory$1.caseAssignStmt(MethodNodeFactory.java:76)
at soot.jimple.internal.JAssignStmt.apply(JAssignStmt.java:238)
at soot.jimple.spark.builder.MethodNodeFactory.handleStmt(MethodNodeFactory.java:69)
at soot.jimple.spark.pag.MethodPAG.buildNormal(MethodPAG.java:179)
at soot.jimple.spark.pag.MethodPAG.build(MethodPAG.java:148)
at soot.jimple.spark.solver.OnFlyCallGraph.processReachables(OnFlyCallGraph.java:64)
at soot.jimple.spark.solver.OnFlyCallGraph.build(OnFlyCallGraph.java:56)
at soot.jimple.spark.builder.ContextInsensitiveBuilder.build(ContextInsensitiveBuilder.java:77)
at soot.jimple.spark.SparkTransformer.internalTransform(SparkTransformer.java:84)
at soot.SceneTransformer.transform(SceneTransformer.java:39)
at soot.Transform.apply(Transform.java:90)
at soot.RadioScenePack.internalApply(RadioScenePack.java:57)
at soot.jimple.toolkits.callgraph.CallGraphPack.internalApply(CallGraphPack.java:49)
at soot.Pack.apply(Pack.java:116)
at soot.PackManager.runWholeProgramPacks(PackManager.java:538)
at soot.PackManager.runPacksNormally(PackManager.java:443)
at soot.PackManager.runPacks(PackManager.java:389)
at apkCFG.CFG.main(CFG.java:79)

file: de.underflow.calc.CalculatorPreferenceActivity.jimple
public class de.underflow.calc.CalculatorPreferenceActivity extends android.preference.PreferenceActivity implements android.preference.Preference$OnPreferenceChangeListener
{
public void <init>()
{
    de.underflow.calc.CalculatorPreferenceActivity $r0;

    $r0 := @this: de.underflow.calc.CalculatorPreferenceActivity;
    specialinvoke $r0.<android.preference.PreferenceActivity: void <init>()>();
    return;
}

private void a()
{
    de.underflow.calc.CalculatorPreferenceActivity $r0;
    boolean $z0;
    android.content.Intent $r1;

    $r0 := @this: de.underflow.calc.CalculatorPreferenceActivity;
    $z0 = specialinvoke $r0.<de.underflow.calc.CalculatorPreferenceActivity: boolean b()>();
    if $z0 == 0 goto label0;

    $r1 = specialinvoke $r0.<de.underflow.calc.CalculatorPreferenceActivity: android.content.Intent c()>();
    virtualinvoke $r0.<de.underflow.calc.CalculatorPreferenceActivity: void startActivity(android.content.Intent)>($r1);

 label0:
    return;
}

static void a(de.underflow.calc.CalculatorPreferenceActivity)
{
    de.underflow.calc.CalculatorPreferenceActivity $r0;

    $r0 := @parameter0: de.underflow.calc.CalculatorPreferenceActivity;
    specialinvoke $r0.<de.underflow.calc.CalculatorPreferenceActivity: void a()>();
    return;
}

private boolean b()
{
    de.underflow.calc.CalculatorPreferenceActivity $r0;
    android.content.Intent $r1;
    android.content.pm.PackageManager $r2;
    java.util.List $r3;
    boolean $z0;

    $r0 := @this: de.underflow.calc.CalculatorPreferenceActivity;
    $r1 = specialinvoke $r0.<de.underflow.calc.CalculatorPreferenceActivity: android.content.Intent c()>();
    $r2 = virtualinvoke $r0.<de.underflow.calc.CalculatorPreferenceActivity: android.content.pm.PackageManager getPackageManager()>();
    $r3 = virtualinvoke $r2.<android.content.pm.PackageManager: java.util.List queryIntentActivities(android.content.Intent,int)>($r1, 65536);
    $z0 = interfaceinvoke $r3.<java.util.List: boolean isEmpty()>();
    if $z0 == 0 goto label0;

    return 0;

 label0:
    return 1;
}

private android.content.Intent c()
{
    de.underflow.calc.CalculatorPreferenceActivity $r0;
    android.content.Intent $r1;
    android.net.Uri $r3;

    $r0 := @this: de.underflow.calc.CalculatorPreferenceActivity;
    $r1 = new android.content.Intent;
    specialinvoke $r1.<android.content.Intent: void <init>(java.lang.String)>("android.intent.action.VIEW");
    $r3 = staticinvoke <android.net.Uri: android.net.Uri parse(java.lang.String)>("market://details?id=de.underflow.calc");
    virtualinvoke $r1.<android.content.Intent: android.content.Intent setData(android.net.Uri)>($r3);
    return $r1;
}

protected void onCreate(android.os.Bundle)
{
    de.underflow.calc.CalculatorPreferenceActivity $r0;
    android.os.Bundle $r1;
    java.lang.String $r2;
    android.preference.PreferenceScreen $r3;
    android.preference.Preference $r4;
    android.preference.EditTextPreference $r5;
    android.widget.EditText $r6;
    android.preference.ListPreference $r7;
    java.lang.CharSequence $r8;
    de.underflow.calc.b $r9;
    boolean $z0;
    de.underflow.calc.c $r10;
    de.underflow.calc.d $r11;

    $r0 := @this: de.underflow.calc.CalculatorPreferenceActivity;
    $r1 := @parameter0: android.os.Bundle;
    specialinvoke $r0.<android.preference.PreferenceActivity: void onCreate(android.os.Bundle)>($r1);
    virtualinvoke $r0.<de.underflow.calc.CalculatorPreferenceActivity: void addPreferencesFromResource(int)>(2131034112);
    $r3 = virtualinvoke $r0.<de.underflow.calc.CalculatorPreferenceActivity: android.preference.PreferenceScreen getPreferenceScreen()>();
    $r4 = virtualinvoke $r3.<android.preference.PreferenceScreen: android.preference.Preference findPreference(java.lang.CharSequence)>("cust_const1_name");
    $r5 = (android.preference.EditTextPreference) $r4;
    $r2 = virtualinvoke $r5.<android.preference.EditTextPreference: java.lang.String getText()>();
    virtualinvoke $r5.<android.preference.EditTextPreference: void setSummary(java.lang.CharSequence)>($r2);
    $r3 = virtualinvoke $r0.<de.underflow.calc.CalculatorPreferenceActivity: android.preference.PreferenceScreen getPreferenceScreen()>();
    $r4 = virtualinvoke $r3.<android.preference.PreferenceScreen: android.preference.Preference findPreference(java.lang.CharSequence)>("cust_const1_def");
    $r5 = (android.preference.EditTextPreference) $r4;
    $r2 = virtualinvoke $r5.<android.preference.EditTextPreference: java.lang.String getText()>();
    virtualinvoke $r5.<android.preference.EditTextPreference: void setSummary(java.lang.CharSequence)>($r2);
    $r6 = virtualinvoke $r5.<android.preference.EditTextPreference: android.widget.EditText getEditText()>();
    virtualinvoke $r6.<android.widget.EditText: void setInputType(int)>(12290);
    $r3 = virtualinvoke $r0.<de.underflow.calc.CalculatorPreferenceActivity: android.preference.PreferenceScreen getPreferenceScreen()>();
    $r4 = virtualinvoke $r3.<android.preference.PreferenceScreen: android.preference.Preference findPreference(java.lang.CharSequence)>("cust_const2_name");
    $r5 = (android.preference.EditTextPreference) $r4;
    $r2 = virtualinvoke $r5.<android.preference.EditTextPreference: java.lang.String getText()>();
    virtualinvoke $r5.<android.preference.EditTextPreference: void setSummary(java.lang.CharSequence)>($r2);
    $r3 = virtualinvoke $r0.<de.underflow.calc.CalculatorPreferenceActivity: android.preference.PreferenceScreen getPreferenceScreen()>();
    $r4 = virtualinvoke $r3.<android.preference.PreferenceScreen: android.preference.Preference findPreference(java.lang.CharSequence)>("cust_const2_def");
    $r5 = (android.preference.EditTextPreference) $r4;
    $r2 = virtualinvoke $r5.<android.preference.EditTextPreference: java.lang.String getText()>();
    virtualinvoke $r5.<android.preference.EditTextPreference: void setSummary(java.lang.CharSequence)>($r2);
    $r6 = virtualinvoke $r5.<android.preference.EditTextPreference: android.widget.EditText getEditText()>();
    virtualinvoke $r6.<android.widget.EditText: void setInputType(int)>(12290);
    $r3 = virtualinvoke $r0.<de.underflow.calc.CalculatorPreferenceActivity: android.preference.PreferenceScreen getPreferenceScreen()>();
    $r4 = virtualinvoke $r3.<android.preference.PreferenceScreen: android.preference.Preference findPreference(java.lang.CharSequence)>("theme_list");
    $r7 = (android.preference.ListPreference) $r4;
    $r8 = virtualinvoke $r7.<android.preference.ListPreference: java.lang.CharSequence getEntry()>();
    virtualinvoke $r7.<android.preference.ListPreference: void setSummary(java.lang.CharSequence)>($r8);
    $r9 = new de.underflow.calc.b;
    specialinvoke $r9.<de.underflow.calc.b: void <init>(de.underflow.calc.CalculatorPreferenceActivity)>($r0);
    virtualinvoke $r7.<android.preference.ListPreference: void setOnPreferenceChangeListener(android.preference.Preference$OnPreferenceChangeListener)>($r9);
    $r3 = virtualinvoke $r0.<de.underflow.calc.CalculatorPreferenceActivity: android.preference.PreferenceScreen getPreferenceScreen()>();
    $r4 = virtualinvoke $r3.<android.preference.PreferenceScreen: android.preference.Preference findPreference(java.lang.CharSequence)>("unit_of_angle");
    $r7 = (android.preference.ListPreference) $r4;
    $r8 = virtualinvoke $r7.<android.preference.ListPreference: java.lang.CharSequence getEntry()>();
    virtualinvoke $r7.<android.preference.ListPreference: void setSummary(java.lang.CharSequence)>($r8);
    virtualinvoke $r7.<android.preference.ListPreference: void setOnPreferenceChangeListener(android.preference.Preference$OnPreferenceChangeListener)>($r0);
    $r2 = virtualinvoke $r5.<android.preference.EditTextPreference: java.lang.String getText()>();
    virtualinvoke $r5.<android.preference.EditTextPreference: void setSummary(java.lang.CharSequence)>($r2);
    $r3 = virtualinvoke $r0.<de.underflow.calc.CalculatorPreferenceActivity: android.preference.PreferenceScreen getPreferenceScreen()>();
    $r4 = virtualinvoke $r3.<android.preference.PreferenceScreen: android.preference.Preference findPreference(java.lang.CharSequence)>("cust_const1_name");
    virtualinvoke $r4.<android.preference.Preference: void setOnPreferenceChangeListener(android.preference.Preference$OnPreferenceChangeListener)>($r0);
    $r3 = virtualinvoke $r0.<de.underflow.calc.CalculatorPreferenceActivity: android.preference.PreferenceScreen getPreferenceScreen()>();
    $r4 = virtualinvoke $r3.<android.preference.PreferenceScreen: android.preference.Preference findPreference(java.lang.CharSequence)>("cust_const1_def");
    virtualinvoke $r4.<android.preference.Preference: void setOnPreferenceChangeListener(android.preference.Preference$OnPreferenceChangeListener)>($r0);
    $r3 = virtualinvoke $r0.<de.underflow.calc.CalculatorPreferenceActivity: android.preference.PreferenceScreen getPreferenceScreen()>();
    $r4 = virtualinvoke $r3.<android.preference.PreferenceScreen: android.preference.Preference findPreference(java.lang.CharSequence)>("cust_const2_name");
    virtualinvoke $r4.<android.preference.Preference: void setOnPreferenceChangeListener(android.preference.Preference$OnPreferenceChangeListener)>($r0);
    $r3 = virtualinvoke $r0.<de.underflow.calc.CalculatorPreferenceActivity: android.preference.PreferenceScreen getPreferenceScreen()>();
    $r4 = virtualinvoke $r3.<android.preference.PreferenceScreen: android.preference.Preference findPreference(java.lang.CharSequence)>("cust_const2_def");
    virtualinvoke $r4.<android.preference.Preference: void setOnPreferenceChangeListener(android.preference.Preference$OnPreferenceChangeListener)>($r0);
    $z0 = specialinvoke $r0.<de.underflow.calc.CalculatorPreferenceActivity: boolean b()>();
    if $z0 == 0 goto label0;

    $r3 = virtualinvoke $r0.<de.underflow.calc.CalculatorPreferenceActivity: android.preference.PreferenceScreen getPreferenceScreen()>();
    $r4 = virtualinvoke $r3.<android.preference.PreferenceScreen: android.preference.Preference findPreference(java.lang.CharSequence)>("rate_app");
    virtualinvoke $r4.<android.preference.Preference: void setEnabled(boolean)>(1);
    $r10 = new de.underflow.calc.c;
    specialinvoke $r10.<de.underflow.calc.c: void <init>(de.underflow.calc.CalculatorPreferenceActivity)>($r0);
    virtualinvoke $r4.<android.preference.Preference: void setOnPreferenceClickListener(android.preference.Preference$OnPreferenceClickListener)>($r10);

 label0:
    $r3 = virtualinvoke $r0.<de.underflow.calc.CalculatorPreferenceActivity: android.preference.PreferenceScreen getPreferenceScreen()>();
    $r4 = virtualinvoke $r3.<android.preference.PreferenceScreen: android.preference.Preference findPreference(java.lang.CharSequence)>("uservoice");
    $r11 = new de.underflow.calc.d;
    specialinvoke $r11.<de.underflow.calc.d: void <init>(de.underflow.calc.CalculatorPreferenceActivity)>($r0);
    virtualinvoke $r4.<android.preference.Preference: void setOnPreferenceClickListener(android.preference.Preference$OnPreferenceClickListener)>($r11);
    return;
}

public boolean onPreferenceChange(android.preference.Preference, java.lang.Object)
{
    de.underflow.calc.CalculatorPreferenceActivity $r0;
    android.preference.Preference $r1;
    java.lang.Object $r2;
    java.lang.String $r3;

    $r0 := @this: de.underflow.calc.CalculatorPreferenceActivity;
    $r1 := @parameter0: android.preference.Preference;
    $r2 := @parameter1: java.lang.Object;
    $r3 = virtualinvoke $r2.<java.lang.Object: java.lang.String toString()>();
    virtualinvoke $r1.<android.preference.Preference: void setSummary(java.lang.CharSequence)>($r3);
    return 1;
}

}

Closing comment (2014-09-02T15:47:14Z): This seems to be related to #243. In both cases, a SetupApplication object is re-used after resetting Soot. Can you check whether the proposed code change over there also works for you?