Skip to content

Commit b990f7f

Browse files
committed
update to 1.4.2 add logger and lowMem and exception handle
1 parent 7178130 commit b990f7f

File tree

9 files changed

+204
-123
lines changed

9 files changed

+204
-123
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,10 @@ java -jar soot-fact-generator.jar -i input.jar -l /usr/lib/jvm/java-8-oracle/jr
6464

6565
另外还额外增加了
6666
- `-i-dir` 指定待分析的jar目录
67-
- `-ld-dir` 指定待分析的依赖目录
67+
- `-ld-dir` 指定待分析的依赖目录
68+
69+
分析很大文件/多文件,比如weblogic这种,可以使用如下命令(需使用最新版),可根据自己情况调整JVM的参数
70+
71+
```
72+
java -Xms8g -Xmx12g -jar soot-fact-generator-1.4.2.jar -d weblogic-out -i-dir /root/ByteCodeDL/weblogic --lowMem --allow-phantom --full -lsystem --ignore-factgen-errors
73+
```

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ gradle.rootProject.ext.commonsCliVersion='1.2'
1010
gradle.rootProject.ext.metadataVersion='2.4.1'
1111
gradle.rootProject.ext.groovyVersion='3.0.9'
1212
gradle.rootProject.ext.clueCommonVersion='3.25.3'
13-
gradle.rootProject.ext.log4jVersion='1.2.17'
1413
gradle.rootProject.ext.spockVersion='2.1-M2-groovy-3.0'
1514
gradle.rootProject.ext.asmVersion = '8.0.1'
1615

@@ -38,8 +37,9 @@ dependencies {
3837
implementation 'net.dongliu:apk-parser:2.6.10' // needed for reading binary XML entries from APK inputs
3938
implementation "org.antlr:antlr4-runtime:${antlrVersion}"
4039
api project(":native-scanner")
41-
api "log4j:log4j:${log4jVersion}" // Logging implementation
4240
implementation 'org.apache.commons:commons-collections4:4.1'
41+
implementation 'org.apache.logging.log4j:log4j-api:2.17.1'
42+
implementation 'org.apache.logging.log4j:log4j-core:2.17.1'
4343

4444
testImplementation "org.codehaus.groovy:groovy-all:${groovyVersion}" // Groovy
4545
testImplementation "org.spockframework:spock-core:${spockVersion}"

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
version=1.4.1
1+
version=1.4.2

src/main/java/org/clyze/doop/common/BasicJavaSupport.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package org.clyze.doop.common;
22

3+
import org.apache.logging.log4j.LogManager;
4+
import org.apache.logging.log4j.Logger;
5+
36
import java.io.File;
47
import java.io.FileInputStream;
58
import java.io.IOException;
@@ -24,6 +27,8 @@ public class BasicJavaSupport {
2427
private final ExecutorService exec = Executors.newFixedThreadPool(3);
2528
public final Collection<String> xmlRoots = ConcurrentHashMap.newKeySet();
2629

30+
private static final Logger logger = LogManager.getLogger(BasicJavaSupport.class);
31+
2732
public BasicJavaSupport(Parameters parameters, ArtifactScanner artScanner) {
2833
this.parameters = parameters;
2934
this.artScanner = artScanner;
@@ -42,15 +47,15 @@ public ExecutorService getExecutor() {
4247
*/
4348
public void preprocessInputs(Database db, Set<String> tmpDirs) throws IOException {
4449
for (String filename : parameters.getInputs()) {
45-
System.out.println("Preprocessing application: " + filename);
50+
logger.info("Preprocessing application: " + filename);
4651
preprocessInput(db, tmpDirs, classesInApplicationJars, filename);
4752
}
4853
for (String filename : parameters.getPlatformLibs()) {
49-
System.out.println("Preprocessing platform library: " + filename);
54+
logger.info("Preprocessing platform library: " + filename);
5055
preprocessInput(db, tmpDirs, classesInLibraryJars, filename);
5156
}
5257
for (String filename : parameters.getDependencies()) {
53-
System.out.println("Preprocessing dependency: " + filename);
58+
logger.info("Preprocessing dependency: " + filename);
5459
preprocessInput(db, tmpDirs, classesInDependencyJars, filename);
5560
}
5661
}
@@ -82,21 +87,21 @@ else if ((isJar || isAar || isZip || isWar) && entryName.endsWith(".xml")) {
8287
// APK archives may contain binary XML and need decoding.
8388
File xmlTmpFile = ArtifactScanner.extractZipEntryAsFile("xml-file", jarFile, entry, entryName);
8489
if (parameters._debug)
85-
System.out.println("Processing XML entry (in " + filename + "): " + entryName);
90+
logger.info("Processing XML entry (in " + filename + "): " + entryName);
8691
XMLFactGenerator.processFile(xmlTmpFile, db, "", parameters._debug);
8792
}
8893
};
8994

9095
if (isWar) {
91-
System.out.println("Processing WAR: " + filename);
96+
logger.info("Processing WAR: " + filename);
9297
// Process WAR inputs.
9398
parameters.processFatArchives(tmpDirs);
9499
}else if (isSpringBoot) {
95-
System.out.println("Processing springBoot: " + filename);
100+
logger.info("Processing springBoot: " + filename);
96101
parameters.processSpringBootArchives(tmpDirs, filename);
97102
parameters.getInputs().forEach(file -> {
98103
try{
99-
// System.out.println(file);
104+
// logger.info(file);
100105
artScanner.processArchive(file, classSet::add, gProc);
101106
}catch (Exception e){
102107
e.printStackTrace();
@@ -112,7 +117,7 @@ else if ((isJar || isAar || isZip || isWar) && entryName.endsWith(".xml")) {
112117
artScanner.processClass(fis, f, classSet::add);
113118
}
114119
} else
115-
System.err.println("WARNING: artifact scanner skips " + filename);
120+
logger.warn("WARNING: artifact scanner skips " + filename);
116121
}
117122

118123
public PropertyProvider getPropertyProvider() {

src/main/java/org/clyze/doop/common/Driver.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package org.clyze.doop.common;
22

3+
import org.apache.logging.log4j.LogManager;
4+
import org.apache.logging.log4j.Logger;
5+
36
import java.util.Collections;
47
import java.util.Set;
58
import java.util.concurrent.*;
@@ -15,18 +18,20 @@ public abstract class Driver<C> {
1518
protected Set<C> _tmpClassGroup;
1619
private int _classCounter;
1720
private final int _totalClasses;
18-
private final int _classSplit = 80;
21+
private final int _classSplit = 800;
1922
private int errors;
2023
public final boolean _ignoreFactGenErrors;
2124

25+
private static final Logger logger = LogManager.getLogger(Driver.class);
26+
2227
protected Driver(int totalClasses, Integer cores, boolean ignoreFactGenErrors) {
2328
this._totalClasses = totalClasses;
2429
this._cores = cores == null? Runtime.getRuntime().availableProcessors() : cores;
2530
this._classCounter = 0;
2631
initTmpClassGroup();
2732
this._ignoreFactGenErrors = ignoreFactGenErrors;
2833

29-
System.out.println("Fact generation cores: " + _cores);
34+
logger.info("Fact generation cores: " + _cores);
3035
}
3136

3237
protected void initTmpClassGroup() {
@@ -67,9 +72,9 @@ public static void waitForExecutorShutdown(ExecutorService executor) throws Doop
6772
try {
6873
boolean res = executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
6974
if (!res)
70-
System.out.println("Executor timeout elapsed.");
75+
logger.info("Executor timeout elapsed.");
7176
} catch (InterruptedException e) {
72-
System.err.println(e.getMessage());
77+
logger.error("waitForExecutorShutdown got interrupt", e);
7378
throw DoopErrorCodeException.error10();
7479
}
7580
}
@@ -78,7 +83,7 @@ private void shutdownExecutor() throws DoopErrorCodeException {
7883
waitForExecutorShutdown(_executor);
7984
if (errorsExist()) {
8085
String msg = "Fact generation failed (" + errors + " errors).";
81-
System.err.println(msg);
86+
logger.error(msg);
8287
if (!_ignoreFactGenErrors)
8388
throw DoopErrorCodeException.error5(msg);
8489
}
@@ -98,6 +103,7 @@ private void generate(C curClass) {
98103
_tmpClassGroup.add(curClass);
99104

100105
if ((_classCounter % _classSplit == 0) || (_classCounter == _totalClasses)) {
106+
logger.info("have submit class {} for fact gen", _classCounter);
101107
_executor.execute(getFactGenRunnable());
102108
initTmpClassGroup();
103109
}

src/main/java/org/clyze/doop/soot/FactGenerator.java

Lines changed: 77 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
import java.util.Set;
88
import java.util.concurrent.ConcurrentHashMap;
99
import java.util.concurrent.atomic.AtomicInteger;
10+
11+
import org.apache.logging.log4j.LogManager;
12+
import org.apache.logging.log4j.Logger;
1013
import org.clyze.doop.common.InstrInfo;
1114
import org.clyze.doop.common.Phantoms;
1215
import org.clyze.doop.common.SessionCounter;
@@ -34,6 +37,8 @@ class FactGenerator implements Runnable {
3437
private final SootParameters sootParameters;
3538
private final SootDriver _driver;
3639

40+
private static final Logger logger = LogManager.getLogger(FactGenerator.class);
41+
3742
FactGenerator(FactWriter writer, Set<SootClass> sootClasses, SootDriver driver, SootParameters sootParameters, Phantoms phantoms)
3843
{
3944
this._writer = writer;
@@ -46,55 +51,87 @@ class FactGenerator implements Runnable {
4651

4752
@Override
4853
public void run() {
49-
final boolean ignoreErrors = _driver._ignoreFactGenErrors;
54+
logger.info("start generate facts");
55+
try{
56+
final boolean ignoreErrors = _driver._ignoreFactGenErrors;
5057

51-
if (!ignoreErrors && _driver.errorsExist())
52-
return;
58+
if (!ignoreErrors && _driver.errorsExist())
59+
return;
60+
61+
for (SootClass _sootClass : _sootClasses) {
62+
try {
63+
_writer.writeClassOrInterfaceType(_sootClass);
64+
65+
for (String mod : getModifiers(_sootClass.getModifiers(), false))
66+
if (!mod.trim().equals(""))
67+
_writer.writeClassModifier(_sootClass, mod);
5368

54-
for (SootClass _sootClass : _sootClasses) {
55-
_writer.writeClassOrInterfaceType(_sootClass);
69+
// the isInterface condition prevents Object as superclass of interface
70+
if (_sootClass.hasSuperclass() && !_sootClass.isInterface()) {
71+
_writer.writeDirectSuperclass(_sootClass, _sootClass.getSuperclass());
72+
}
5673

57-
for (String mod : getModifiers(_sootClass.getModifiers(), false))
58-
if (!mod.trim().equals(""))
59-
_writer.writeClassModifier(_sootClass, mod);
74+
for (SootClass i : _sootClass.getInterfaces()) {
75+
_writer.writeDirectSuperinterface(_sootClass, i);
76+
}
6077

61-
// the isInterface condition prevents Object as superclass of interface
62-
if (_sootClass.hasSuperclass() && !_sootClass.isInterface()) {
63-
_writer.writeDirectSuperclass(_sootClass, _sootClass.getSuperclass());
78+
_sootClass.getFields().forEach(this::generate);
79+
80+
for (SootMethod m : new ArrayList<>(_sootClass.getMethods())) {
81+
SessionCounter session = new SessionCounter();
82+
try {
83+
generate(m, session);
84+
} catch (Throwable t) {
85+
// Map<Thread,StackTraceElement[]> liveThreads = Thread.getAllStackTraces();
86+
// for (Iterator<Thread> i = liveThreads.keySet().iterator(); i.hasNext(); ) {
87+
// Thread key = i.next();
88+
// logger.error("Thread " + key.getName());
89+
// StackTraceElement[] trace = liveThreads.getLibrary(key);
90+
// for (int j = 0; j < trace.length; j++) {
91+
// logger.error("\tat " + trace[j]);
92+
// }
93+
// }
94+
String msg = "Error while processing method: " + m ;
95+
logger.error(msg, t);
96+
if (!ignoreErrors) {
97+
// Inform the driver. This is safer than throwing an
98+
// exception, since it could be lost due to the executor
99+
// service running this class.
100+
_driver.markError();
101+
return;
102+
}
103+
}
104+
}
105+
}catch (Exception e){
106+
if (_sootClass != null){
107+
logger.error("handle class {}.{} error",_sootClass.getJavaStyleName(), e);
108+
}
109+
}
64110
}
65111

66-
for (SootClass i : _sootClass.getInterfaces()) {
67-
_writer.writeDirectSuperinterface(_sootClass, i);
112+
if (sootParameters._lowMem && !sootParameters._generateJimple){
113+
gcMethodBody(_sootClasses);
68114
}
115+
}catch (Exception e){
116+
logger.error("FactGenerator run occur error ", e);
117+
}
69118

70-
_sootClass.getFields().forEach(this::generate);
119+
logger.info("finish generator facts");
71120

72-
for (SootMethod m : new ArrayList<>(_sootClass.getMethods())) {
73-
SessionCounter session = new SessionCounter();
74-
try {
75-
generate(m, session);
76-
} catch (Throwable t) {
77-
// Map<Thread,StackTraceElement[]> liveThreads = Thread.getAllStackTraces();
78-
// for (Iterator<Thread> i = liveThreads.keySet().iterator(); i.hasNext(); ) {
79-
// Thread key = i.next();
80-
// System.err.println("Thread " + key.getName());
81-
// StackTraceElement[] trace = liveThreads.getLibrary(key);
82-
// for (int j = 0; j < trace.length; j++) {
83-
// System.err.println("\tat " + trace[j]);
84-
// }
85-
// }
86-
String msg = "Error while processing method: " + m + ": " + t.getMessage();
87-
System.err.println(msg);
88-
if (!ignoreErrors) {
89-
// Inform the driver. This is safer than throwing an
90-
// exception, since it could be lost due to the executor
91-
// service running this class.
92-
_driver.markError();
93-
return;
94-
}
121+
}
122+
123+
private void gcMethodBody(Set<SootClass> sootClasses){
124+
logger.info("start gcMethodBody");
125+
for (SootClass sootClass : sootClasses) {
126+
for (SootMethod method : sootClass.getMethods()) {
127+
if (method.hasActiveBody()){
128+
method.setActiveBody(null);
95129
}
96130
}
97131
}
132+
logger.info("start System.gc");
133+
System.gc();
134+
logger.info("finish gcMethodBody");
98135
}
99136

100137
private void generate(SootField f)
@@ -207,7 +244,7 @@ void generate(SootMethod m, SessionCounter session) {
207244
m.retrieveActiveBody();
208245
// } // synchronizing so broadly = giving up on Soot's races
209246

210-
// System.err.println("Found method without active body: " + m.getSignature());
247+
// logger.error("Found method without active body: " + m.getSignature());
211248
methodsWithoutActiveBodies.incrementAndGet();
212249
}
213250

@@ -227,8 +264,7 @@ void generate(SootMethod m, SessionCounter session) {
227264
m.setActiveBody(b0);
228265
}
229266
} catch (RuntimeException ex) {
230-
System.err.println("Fact generation failed for method " + m.getSignature() + ".");
231-
ex.printStackTrace();
267+
logger.error("Fact generation failed for method " + m.getSignature() + ".", ex);
232268
throw ex;
233269
}
234270
}
@@ -345,7 +381,7 @@ private void generatePhantom(Object cause) {
345381
else if (cause instanceof SootMethod)
346382
_writer.writePhantomMethod(_writer._rep.signature((SootMethod)cause));
347383
else
348-
System.err.println("Ignoring phantom cause: " + cause);
384+
logger.error("Ignoring phantom cause: " + cause);
349385
}
350386

351387
/**

0 commit comments

Comments
 (0)