Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

It is irrational that argument "--main-class" requires not null #7

Closed
djaekim opened this issue Sep 15, 2022 · 16 comments
Closed

It is irrational that argument "--main-class" requires not null #7

djaekim opened this issue Sep 15, 2022 · 16 comments
Labels
type: task A general task

Comments

@djaekim
Copy link

djaekim commented Sep 15, 2022

Hello =)

I am trying to run tai-e on a jar project I downloaded from this link. Specifically on commons-io-2.9.0-test-sources.jar.

To run this, I used following argument below.

This is the path of the .jar
-cp "XXX/XX/jar/commons-io-2.9.0-test-sources.jar"
This is the path of the .class file
--input-classes="org/apache/commons/io/input/BoundedInputStreamTest.class"
This is just trying to reproduce example posted on your documentation
-a pta=cs:2-type;merge-string-constants:true

Unfortunately, I got errors below. I was wondering if you could help me to resolve this issue?

Tai-e starts ...
Writing options to output\options.yml
Writing analysis plan to output\tai-e-plan.yml
WorldBuilder starts ...
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.charAt(int)" because "option" is null
	at soot.options.Options.parse(Options.java:136)
	at soot.Main.processCmdLine(Main.java:85)
	at soot.Main.run(Main.java:248)
	at pascal.taie.frontend.soot.SootWorldBuilder.runSoot(SootWorldBuilder.java:246)
	at pascal.taie.frontend.soot.SootWorldBuilder.build(SootWorldBuilder.java:73)
	at pascal.taie.Main.lambda$buildWorld$3(Main.java:121)
	at pascal.taie.util.Timer.lambda$runAndCount$0(Timer.java:112)
	at pascal.taie.util.Timer.runAndCount(Timer.java:93)
	at pascal.taie.util.Timer.runAndCount(Timer.java:111)
	at pascal.taie.util.Timer.runAndCount(Timer.java:107)
	at pascal.taie.Main.buildWorld(Main.java:116)
	at pascal.taie.Main.lambda$main$0(Main.java:55)
	at pascal.taie.util.Timer.lambda$runAndCount$0(Timer.java:112)
	at pascal.taie.util.Timer.runAndCount(Timer.java:93)
	at pascal.taie.util.Timer.runAndCount(Timer.java:111)
	at pascal.taie.util.Timer.runAndCount(Timer.java:107)
	at pascal.taie.Main.main(Main.java:48)

Process finished with exit code 1

Thank you so much!
@zhangt2333
Copy link
Member

zhangt2333 commented Sep 16, 2022

This is the path of the .class file
--input-classes="org/apache/commons/io/input/BoundedInputStreamTest.class"

An obvious issue is that argument --input-classes should follow the format of fully-qualified name in Java, e.g., org.apache.commons.io.input.BoundedInputStreamTest but not org/apache/commons/io/input/BoundedInputStreamTest.class.

@zhangt2333 zhangt2333 added status: waiting-for-feedback We need additional information before we can continue and removed status: waiting-for-feedback We need additional information before we can continue labels Sep 16, 2022
@djaekim
Copy link
Author

djaekim commented Sep 16, 2022

After changing it to fully qualified name. I still get the same error.

@zhangt2333
Copy link
Member

zhangt2333 commented Sep 16, 2022

Could you provide the full arguments you used?

@djaekim
Copy link
Author

djaekim commented Sep 16, 2022

Could you provide the fully arguments you used?

-cp XX\jar\commons-io-2.9.0-test-sources.jar --input-classes="org.apache.commons.io.input.BoundedInputStreamTest" -a pta=cs:2-type;merge-string-constants:true

Thank you!

@zhangt2333
Copy link
Member

zhangt2333 commented Sep 16, 2022

-cp XX\jar\commons-io-2.9.0-test-sources.jar --input-classes="org.apache.commons.io.input.BoundedInputStreamTest" -a pta=cs:2-type;merge-string-constants:true

Hi!

-m is currently required not null (We will solve this issue shortly, then inform you).

In your scene, a temporary solution now is to choose one of --input-classes as -m. That is, with arguments -cp XX\jar\commons-io-2.9.0-test-sources.jar --input-classes=org.apache.commons.io.input.BoundedInputStreamTest -m org.apache.commons.io.input.BoundedInputStreamTest -a pta=cs:2-type;merge-string-constants:true, Tai-e will run normally.

@djaekim
Copy link
Author

djaekim commented Sep 16, 2022

Hi thank you so much,

I tried to run it based on your suggestion with args below:

-cp XX\jar\commons-io-2.9.0-test-sources.jar --input-classes="org.apache.commons.io.input.BoundedInputStreamTest" -m "org.apache.commons.io.input.BoundedInputStreamTest" -a pta=cs:2-type;merge-string-constants:true

However, there was another error

Exception in thread "main" soot.JavaClassProvider$JarException: Class org.apache.commons.io.input.BoundedInputStreamTest was found in an archive, but Soot doesn't support reading source files out of an archive
	at soot.JavaClassProvider.find(JavaClassProvider.java:75)
	at soot.SourceLocator.getClassSource(SourceLocator.java:187)
	at soot.Scene.tryLoadClass(Scene.java:969)
	at soot.Scene.loadBasicClasses(Scene.java:1713)
	at soot.Scene.loadNecessaryClasses(Scene.java:1806)
	at soot.Main.run(Main.java:254)
	at pascal.taie.frontend.soot.SootWorldBuilder.runSoot(SootWorldBuilder.java:247)

Thank you,
kim

@zhangt2333
Copy link
Member

zhangt2333 commented Sep 16, 2022

I will take a deep look at this issue later.

Currently, a workaround is to pass the decompressed directory (not a jar file) as class path.

@zhangt2333
Copy link
Member

Exception in thread "main" soot.JavaClassProvider$JarException: Class org.apache.commons.io.input.BoundedInputStreamTest was found in an archive, but Soot doesn't support reading source files out of an archive
	at soot.JavaClassProvider.find(JavaClassProvider.java:75)
	at soot.SourceLocator.getClassSource(SourceLocator.java:187)
	at soot.Scene.tryLoadClass(Scene.java:969)
	at soot.Scene.loadBasicClasses(Scene.java:1713)
	at soot.Scene.loadNecessaryClasses(Scene.java:1806)
	at soot.Main.run(Main.java:254)
	at pascal.taie.frontend.soot.SootWorldBuilder.runSoot(SootWorldBuilder.java:247)

In the above exception, the Soot’s frontend doesn't support reading Java source files out of an archive. So we need pass the decompressed directory (but not a jar) as class path.

In addition, as stated below, we recommend analyzing the bytecode for real-world program. In your case, is that using commons-io-2.9.0-tests.jar instead of commons-io-2.9.0-test-sources.jar? Maybe so, I guess.

Soot’s frontend for Java source files is outdated (only partially supports Java version up to 7) and not very robust. Meanwhile, Soot’s frontend for bytecode files, which does not keep variable names though, is more robust (it virtually works well for the .class files compiled by up to Java 17) than the frontend for Java source files. Thus, for real-world applications, Tai-e usually analyzes bytecode.

@zhangt2333 zhangt2333 changed the title Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.charAt(int)" because "option" is null It is irrational that argument "--main-class" is required to be specified Sep 17, 2022
@zhangt2333 zhangt2333 added the type: task A general task label Sep 17, 2022
@zhangt2333
Copy link
Member

zhangt2333 commented Sep 19, 2022

-m is currently required not null (We will solve this issue shortly, then inform you).

After the commit d9784e3, it only requires that at least one of --main-class and --input-classes be specifie.

That means -m can be ignored in your case. (You can try on the latest commit)

@zhangt2333 zhangt2333 changed the title It is irrational that argument "--main-class" is required to be specified It is irrational that argument "--main-class" requires not null Sep 19, 2022
@zhangt2333
Copy link
Member

No response for more than 7 days.

Closing now.

@djaekim
Copy link
Author

djaekim commented Oct 14, 2022

Hello, I apologize for the delay.

For running real world project, I want to run, for instance, inter-procedural analysis for each individual Junit Test Case to see how data might flow from and to the specific test case.

To do this, I want to get minimal execution using existing analyzer before writing some custom analyzer. I am still having trouble running this.

If I want to analyze a specific Junit method (not necessarily static main method), how would I go about instrumenting it?

Currently, my cmd looks like this
-cp C:\Users\djaek\Documents\PhD\Inheritance\inheritance_extractor\analysis_python\jar\some.jar ----input-classes=org.apache.commons.io.input.BoundedInputStreamTest -a pta=cs:2-type;merge-string-constants:true

However, there was issue with was that it must be decompressed or something.

I was wondering, what would be the exact step to go about this?

@zhangt2333
Copy link
Member

If I want to analyze a specific Junit method (not necessarily static main method), how would I go about instrumenting it?

see #9.

However, there was issue with was that it must be decompressed or something.

It is not clear I cannot get what you mean. Exception infomation should be provided if it exists.

@djaekim
Copy link
Author

djaekim commented Oct 15, 2022

Hi, I am still getting the same error, when executing command below

--class-path
C:\\Users\\djaek\\Documents\\PhD\\Inheritance\\inheritance_extractor\\analysis_python\\jar\\commons-collections\\
--input-classes=org.apache.commons.collections4.functors.AllPredicateTest
--analysis
pta=cs:2-type

the -class-path is the directory to bytecode

"C:\Program Files\Java\jdk-18.0.2\bin\java.exe" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:55685,suspend=y,server=n -javaagent:C:\Users\djaek\AppData\Local\JetBrains\IdeaIC2022.2\captureAgent\debugger-agent.jar=file:/C:/Users/djaek/AppData/Local/Temp/capture.props -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath "C:\Users\djaek\Documents\...\analysis_python\Snapshot_Analysis\Tai-e\out\production\classes;C:\Users\djaek\Documents\...\Snapshot_Analysis\Tai-e\out\production\resources;C:\Users\djaek\Documents\...\Snapshot_Analysis\Tai-e\lib\sootclasses-modified.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\info.picocli\picocli\4.6.1\49a67ee4b4d9722fa60f3f9ffaffa72861c32966\picocli-4.6.1.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-core\2.16.0\ca12fb3902ecfcba1e1357ebfc55407acec30ede\log4j-core-2.16.0.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-api\2.16.0\4727d93a76616ffc4149dffac5801827c0f4ac71\log4j-api-2.16.0.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.dataformat\jackson-dataformat-yaml\2.12.2\8c549fb29f390f6fd0c20cf0a1d83f7e38dc7ffb\jackson-dataformat-yaml-2.12.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.soot-oss\soot\4.3.0-20211223.212205-256\649b6b2af64434fb2659343f06d2893cd25ace91\soot-4.3.0-20211223.212205-256.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.slf4j\slf4j-nop\1.7.5\3482f4546a52dc63d0c8e829338f26a77e5eab1b\slf4j-nop-1.7.5.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-databind\2.12.2\5f9d79e09ebf5d54a46e9f4543924cf7ae7654e0\jackson-databind-2.12.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-core\2.12.2\8df50138521d05561a308ec2799cc8dda20c06df\jackson-core-2.12.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.yaml\snakeyaml\1.27\359d62567480b07a679dc643f82fc926b100eed5\snakeyaml-1.27.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\commons-io\commons-io\2.7\3f2bd4ba11c4162733c13cc90ca7c7ea09967102\commons-io-2.7.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.smali\dexlib2\2.5.2\8b664182af455b0757a7f59a42020fa5608c7d0e\dexlib2-2.5.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.ow2.asm\asm-util\9.2\fbc178fc5ba3dab50fd7e8a5317b8b647c8e8946\asm-util-9.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.ow2.asm\asm-commons\9.2\f4d7f0fc9054386f2893b602454d48e07d4fbead\asm-commons-9.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.ow2.asm\asm-tree\9.2\d96c99a30f5e1a19b0e609dbb19a44d8518ac01e\asm-tree-9.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.ow2.asm\asm\9.2\81a03f76019c67362299c40e0ba13405f5467bff\asm-9.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\xmlpull\xmlpull\1.1.3.4d_b4_min\6dcdbef481ff8fbac336a47048048b2b31855015\xmlpull-1.1.3.4d_b4_min.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\de.upb.cs.swt\axml\2.1.0-SNAPSHOT\32374202d6343f6d0de434918469aa7316017168\axml-2.1.0-SNAPSHOT.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\ca.mcgill.sable\polyglot\2006\f0e528051faa260d83f53d58275954d973231ce7\polyglot-2006.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\de.upb.cs.swt\heros\1.2.3-SNAPSHOT\bdea1884d3f1ec9d57dbc03ca99cb17ef5c0819d\heros-1.2.3-SNAPSHOT.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\ca.mcgill.sable\jasmin\3.0.3-SNAPSHOT\573ac2f66d968fd40898b6458e888f2b56351e1d\jasmin-3.0.3-SNAPSHOT.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.slf4j\slf4j-api\1.7.32\cdcff33940d9f2de763bc41ea05a0be5941176c3\slf4j-api-1.7.32.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\javax.annotation\javax.annotation-api\1.3.2\934c04d3cfef185a8008e7bf34331b79730a9d43\javax.annotation-api-1.3.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.glassfish.jaxb\jaxb-runtime\2.4.0-b180830.0438\2a0705ce8aa988b691c70e8bdcc1613050a148a2\jaxb-runtime-2.4.0-b180830.0438.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\javax.xml.bind\jaxb-api\2.4.0-b180830.0359\b54184b7dcab2031add3f525550c7f1b7e12209d\jaxb-api-2.4.0-b180830.0359.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-annotations\2.12.2\a770cc4c0a1fb0bfd8a150a6a0004e42bc99fca\jackson-annotations-2.12.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.ow2.asm\asm-analysis\9.2\7487dd756daf96cab9986e44b9d7bcb796a61c10\asm-analysis-9.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.functionaljava\functionaljava\4.2\f26bdd90a8d6b6faeb38ab2ba4c39580c1eb989f\functionaljava-4.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\ca.mcgill.sable\java_cup\0.9.2\f36b758580fb9d472bfd5965aa9ac807fa66d242\java_cup-0.9.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\javax.activation\javax.activation-api\1.2.0\85262acf3ca9816f9537ca47d5adeabaead7cb16\javax.activation-api-1.2.0.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.glassfish.jaxb\txw2\2.4.0-b180830.0438\31bae7fb5924472b3243b265b47cb741da715419\txw2-2.4.0-b180830.0438.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.sun.istack\istack-commons-runtime\3.0.7\c197c86ceec7318b1284bffb49b54226ca774003\istack-commons-runtime-3.0.7.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.jvnet.staxex\stax-ex\1.8\8cc35f73da321c29973191f2cf143d29d26a1df7\stax-ex-1.8.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.sun.xml.fastinfoset\FastInfoset\1.2.15\bb7b7ec0379982b97c62cd17465cb6d9155f68e8\FastInfoset-1.2.15.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.google.guava\failureaccess\1.0.1\1dcf1de382a0bf95a3d8b0849546c88bac1292c9\failureaccess-1.0.1.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.google.guava\listenablefuture\9999.0-empty-to-avoid-conflict-with-guava\b421526c5f297295adef1c886e5246c39d4ac629\listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.google.code.findbugs\jsr305\3.0.2\25ea2e8b0c338a877313bd4672d3fe056ea78f0d\jsr305-3.0.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.google.guava\guava\27.1-android\a80ef47421d6607e749f8b7282dd7dee61adfea7\guava-27.1-android.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.checkerframework\checker-compat-qual\2.5.2\dc0b20906c9e4b9724af29d11604efa574066892\checker-compat-qual-2.5.2.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.google.errorprone\error_prone_annotations\2.2.0\88e3c593e9b3586e1c6177f89267da6fc6986f0c\error_prone_annotations-2.2.0.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\com.google.j2objc\j2objc-annotations\1.1\ed28ded51a8b1c6b112568def5f4b455e6809019\j2objc-annotations-1.1.jar;C:\Users\djaek\.gradle\caches\modules-2\files-2.1\org.codehaus.mojo\animal-sniffer-annotations\1.17\f97ce6decaea32b36101e37979f8b647f00681fb\animal-sniffer-annotations-1.17.jar;C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2022.2.1\lib\idea_rt.jar" pascal.taie.Main --class-path "C:\\Users\\djaek\\Documents\\...\\jar\\commons-collections\\\\" --input-classes=org.apache.commons.collections4.functors.AllPredicateTest --analysis pta=cs:2-type;only-app:true
Connected to the target VM, address: '127.0.0.1:55685', transport: 'socket'
Tai-e starts ...
Writing options to output\options.yml
Writing analysis plan to output\tai-e-plan.yml
WorldBuilder starts ...
java-benchmarks\JREs\jre1.6\jce.jar;java-benchmarks\JREs\jre1.6\jsse.jar;java-benchmarks\JREs\jre1.6\rt.jar;C:\\Users\\djaek\\Documents\\PhD\\Inheritance\\inheritance_extractor\\analysis_python\\jar\\commons-collections\\
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.charAt(int)" because "option" is null
	at soot.options.Options.parse(Options.java:136)
	at soot.Main.processCmdLine(Main.java:85)
	at soot.Main.run(Main.java:248)
	at pascal.taie.frontend.soot.SootWorldBuilder.runSoot(SootWorldBuilder.java:247)
	at pascal.taie.frontend.soot.SootWorldBuilder.build(SootWorldBuilder.java:74)
	at pascal.taie.Main.lambda$buildWorld$3(Main.java:121)
	at pascal.taie.util.Timer.lambda$runAndCount$0(Timer.java:112)
	at pascal.taie.util.Timer.runAndCount(Timer.java:93)
	at pascal.taie.util.Timer.runAndCount(Timer.java:111)
	at pascal.taie.util.Timer.runAndCount(Timer.java:107)
	at pascal.taie.Main.buildWorld(Main.java:116)
	at pascal.taie.Main.lambda$main$0(Main.java:55)
	at pascal.taie.util.Timer.lambda$runAndCount$0(Timer.java:112)
	at pascal.taie.util.Timer.runAndCount(Timer.java:93)
	at pascal.taie.util.Timer.runAndCount(Timer.java:111)
	at pascal.taie.util.Timer.runAndCount(Timer.java:107)
	at pascal.taie.Main.main(Main.java:48)
Disconnected from the target VM, address: '127.0.0.1:55685', transport: 'socket'

Finally, I really appreciate the documentations, but I am still having trouble running a simple example. I was wondering if it would be possible to make available some kind of complete example on analyzing a real world apache project, where it runs some reproducible analysis example from start to finish. I feel like this would help make better accessibility of the features. Thank you.

@zhangt2333
Copy link
Member

	at pascal.taie.frontend.soot.SootWorldBuilder.runSoot(SootWorldBuilder.java:247)
	at pascal.taie.frontend.soot.SootWorldBuilder.build(SootWorldBuilder.java:74)

I notice that the line number of method runSoot in the stack frame is line 247.

It seems to imply that the Tai-e you are using is under this commit 9d9d15a but not d9784e3 (as I mentioned in #7 (comment)).

private static void runSoot(String[] args) {
try {
soot.Main.v().run(args);
} catch (SootResolver.SootClassNotFoundException e) {
throw new RuntimeException(e.getMessage()

private static void runSoot(String[] args) {
try {
soot.Main.v().run(args);
} catch (SootResolver.SootClassNotFoundException e) {
throw new RuntimeException(e.getMessage()

Could you pull the latest code and try it again?

@djaekim
Copy link
Author

djaekim commented Oct 16, 2022

	at pascal.taie.frontend.soot.SootWorldBuilder.runSoot(SootWorldBuilder.java:247)
	at pascal.taie.frontend.soot.SootWorldBuilder.build(SootWorldBuilder.java:74)

I notice that the line number of method runSoot in the stack frame is line 247.

It seems to imply that the Tai-e you are using is under this commit 9d9d15a but not d9784e3 (as I mentioned in #7 (comment)).

private static void runSoot(String[] args) {
try {
soot.Main.v().run(args);
} catch (SootResolver.SootClassNotFoundException e) {
throw new RuntimeException(e.getMessage()

private static void runSoot(String[] args) {
try {
soot.Main.v().run(args);
} catch (SootResolver.SootClassNotFoundException e) {
throw new RuntimeException(e.getMessage()

Could you pull the latest code and try it again?

Thank you, it's working now.

Another question I have is I want to use plugin to analyze specific Junit Test Method. What is the general step done to do that? I tried to use existing plugin just as a proof-of-concept. Tai-e\src\main\java\pascal\taie\analysis\pta\plugin\taint\TaintAnalysis.java

For example, let's say my -input-classes="some test.java file to analyze". To access this class's Junit method in the in the TaintAnalysis's onStart to add to the solver.addEntryPoint(), I used below code. It that ok?

        Iterable<JClass> iterable = World.get().getClassHierarchy().applicationClasses()::iterator;
        for (JClass s : iterable) {
           for(JMethod m : s.getDeclaredMethods()){
               solver.addEntryPoint(new EntryPoint(m,
                       new MainEntryPointParamProvider(m, solver)));
           }
        }

I am also using

-cp
\repo\dubbo\
--input-classes=dubbo-cluster.target.test-classes.org.apache.dubbo.rpc.cluster.loadbalance.ConsistentHashLoadBalanceTest
-a
"pta=action:dump;action-file:output.dump"
-ap
-scope
REACHABLE  

I used -ap because I only want to analyze specific junit file, but this file depends on other files. Would this affect analysis? For example, I got the below logs.
image

Another question I have is, for this above analysis, it gave an output.dump that is for entire source code, but not the specified files. How to only get output for the specified files?

@zhangt2333
Copy link
Member

zhangt2333 commented Oct 17, 2022

Another question I have is I want to use plugin to analyze specific Junit Test Method. What is the general step done to do that?

Refer to wiki, #9, write a plugin of your own, and activate it.

For example, let's say my -input-classes="some test.java file to analyze". To access this class's Junit method in the in the TaintAnalysis's onStart to add to the solver.addEntryPoint(), I used below code. It that ok?

        Iterable<JClass> iterable = World.get().getClassHierarchy().applicationClasses()::iterator;
        for (JClass s : iterable) {
           for(JMethod m : s.getDeclaredMethods()){
               solver.addEntryPoint(new EntryPoint(m,
                       new MainEntryPointParamProvider(m, solver)));
           }
        }

It seems that this would treat all methods of all classes in the World (the classes being analyzed) as public static void main(String[] args). I don't think it's what you want. Maybe you can take the following steps:

  1. Gets the specific class from ClassHierarchy, e.g., by World.get().getClassHierarchy().getClass("org.apache.commons.collections4.functors.AllPredicateTest");

  2. Gets all methods in the class and filters out the ones with the @Test annotation. May need to use pascal.taie.language.classes.JClass#getDeclaredMethods and pascal.taie.language.classes.ClassMember#hasAnnotation.

  3. Adds entrypoint by pascal.taie.analysis.pta.core.solver.Solver#addEntryPoint. Note that you may need to mock the parameters of the method. See also pascal.taie.analysis.pta.core.solver.ParamProvider and its three subclasses.

I used -ap because I only want to analyze specific junit file, but this file depends on other files. Would this affect analysis? For example, I got the below logs. image

See #3.

Another question I have is, for this above analysis, it gave an output.dump that is for entire source code, but not the specified files. How to only get output for the specified files?

There is no option to support this action. If you want to filter the pointers to be dumped, consider modifying the following code:

private static void dumpPointers(
PrintStream out, Collection<? extends Pointer> pointers, String desc) {
out.println(HEADER + desc);
pointers.stream()
.sorted(Comparator.comparing(Pointer::toString))
.forEach(p -> out.println(p + SEP + Streams.toString(p.objects())));
out.println();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: task A general task
Projects
None yet
Development

No branches or pull requests

2 participants