2017-06-08 18 views
6

Tôi đang viết một IntelliJ-Plugin để phân tích mã chương trình java. Vì vậy, tôi sử dụng Soot để viết phân tích tĩnh. Mỗi khi người dùng kích hoạt các phân tích hành động của plugin của tôi, tôi lấy hiện tại VirtualFile của bối cảnh hiện nay như thế này:Soot: Tải lại lớp học sau khi tập tin nguồn đã thay đổi

FileEditorManager manager = FileEditorManager.getInstance(e.getProject()); 
VirtualFile files[] = manager.getSelectedFiles(); 
toAnalyse = files[0]; [...] 

Khi tôi kiểm tra nội dung của tập tin này tất cả các thay đổi được áp dụng. Sau này tôi đang tải lớp tôi muốn phân tích trong Soot.

String dir = toAnalyse.getParent().getPath() ; 
Options.v().setPhaseOption("jb", "use-original-names"); 
Options.v().set_soot_classpath(System.getProperty("java.home")+";"+ dir); 
c = Scene.v().loadClassAndSupport(name); 
/*no analyse c*/ 

Điều này hoàn toàn phù hợp với tôi. Nhưng bây giờ đến vấn đề của tôi: Nếu tôi thay đổi sth. trong trường hợp thử nghiệm của plugin của tôi và kích hoạt lại phân tích tương tự, không có gì thay đổi.

Tôi đã cố gắng gì cho đến nay?

Tôi đặt tùy chọn sau:

Options.v().set_dump_body(Arrays.asList("jb")); 
Options.v().set_dump_cfg(Arrays.asList("jb")); 
Options.v().set_allow_phantom_refs(true); 
Options.v().set_whole_program(true); 

tôi cũng loại bỏ tất cả các lớp học bằng tay

như thế này:

Chain<SootClass> classes = Scene.v().getClasses(); 
Stack<SootClass> stack = new Stack<>(); 
for(SootClass s : classes) 
    stack.push(s); 
while(!stack.empty()) 
    Scene.v().removeClass(stack.pop()); 

và bắt đầu lại chương trình.

Trả lời

5

Tôi đã giải quyết vấn đề này.

SootClass c = Scene.v().loadClassAndSupport(name); 
// ... 
c.setResolvingLevel(0); 
G.reset(); 

G.reset() đặt lại tất cả các trường hợp đơn lẻ. Do đó tất cả kết quả được lưu trong bộ nhớ cache sẽ bị ghi đè bằng cách gọi lại hành động này.

public static Scene v() { 
    return G.v().soot_Scene(); 
} 

this.instance_soot_Scenenull sau khi gọi G.reset().

Do đó đoạn mã sau:

public Scene soot_Scene() { 
    if(this.instance_soot_Scene == null) { 
     synchronized(this) { 
      if(this.instance_soot_Scene == null) { 
       this.instance_soot_Scene = new Scene(this.g); 
      } 
     } 
    } 

    return this.instance_soot_Scene; 
} 

trả về một đối tượng mới với một bộ nhớ cache kết quả trống.

Các vấn đề liên quan