Thực nghiệm
3.2. Phân tích chương trình cùng với SOOT trong Eclipse
Trong phần này, luận văn thực nghiệm với phân tích tính sống của biến. Các bước thực thi trong SOOT:
- Bước 1: Phân tích tính sống của biến là phân tích lùi (backward), do đó ta chọn
BackwardFlowAnalysis:
- Bước 2: Xây dựng dàn:
+ Dàn được xây dựng ở đây là tập các biến có trong chương trình, Ví dụ: {f, uu_f, n}
+ Phép toán nối được chọn ở đây là phép hợp (∪)
Trong SOOT, ta sử dụng ArraySparseSet để cài đặt cho tập dàn. Cài đặt hai hàm copy(), merge() v v Copy( ) merge( ) w w1 w2
Hình 3.2: Phương thức copy() và merge() trong SOOT
void merge(Set w1, Set w2, Set v); void copy(Set w, Set v);
SOOT cung cấp các tập đặc biệt gọi là FlowSet s, hỗ trợ các phương thức để cài đặt các phép toán trên dàn như: ToppedSet, ArraySparseSet,
ArrayPackedSet: •z = x ∩ y x.inter section(y, z); • z = x ∪ y a.union(b, c); • t = x x.com plement(t); • t = t ∪ {v} d.add(v);
Dưới đây, các hàm copy(), và merger() cho phân tích + Phương thức copy(): protected void copy(Set src, Set dest) {
dest.clear(); dest.addAll(src); }
+ Phương thức merge(): Trong phân tích tính sống của biến, một biến v
void merge(...) { dest.clear();
dest.addAll(w1Set); dest.addAll(w2Set); }
-Bước 3: Phương trình luồng dữ liệu: Ví dụ, một biến sống trong phép gán f=f*n; ta phải loại bỏ biến f vế trái và sử dụng lại hai biến f và n trong vế phải. Do đó hàm sinh phương trình luồng cho phân tích là:
protected void flowThrough(Set srcValue, Unit u, Set destValue){ for (ValueBox box : ut.getDefBoxes())
{ Value value = box.getValue(); if( value instanceof Local ) dest.remove( value );
}
for (ValueBox box : ut.getUseBoxes()) { Value value = box.getValue(); if (value instanceof Local) dest.add(value);
}
for (ValueBox box : ut.getUseBoxes()) { Value value = box.getValue(); if (value instanceof Local) dest.add(value);
} }
- Bước 4: Các phương thức khởi tạo luồng vào/ra: Set newInitialFlow(){
return new HashSet(); }
Set entryInitialFlow(){ return new HashSet(); }
- Bước 5: Khởi tạo phân tích
LivenessAnalysis(UnitGraph g){ super(g);
doAnalysis(); }
Hình ảnh chạy phân tích tính sống của biến với SOOT:
KẾTLUẬN LUẬN
Phân tích chương trình tĩnh là kỹ thuật đang thu hút sự quan tâm của thế
giới bởi những ứng dụng của nó mang lại. Trong quá trình thực hiện luận văn này, tôi đã tìm hiểu những kiến thức nền tảng về phân tích chương trình - là một khâu vô cùng quan trọng giúp phát hiện lỗi và tối ưu hóa chương trình để nhằm nâng cao chất lượng phần mềm. Cụ thể, luận văn đã đạt trình bày tổng quan về phân tích chương trình tĩnh. Trong đó, nêu ra các khái niệm liên quan đến phân tích chương trình tĩnh, những điểm mạnh và mặt yếu, các kỹ thuật chính về phân tích chương trình tĩnh đang được giới học thuật nghiên cứu. Tiếp theo đó là các lý thuyết nền tảng liên quan đến phân tích chương trình tĩnh như cách xây dựng đồ thị luồng dữ liệu, các lý thuyết toán học như lý thuyết Dàn, và các thuật toán tìm điểm cố định. Từ những kiến thức nền tảng đó, luận văn đã tiếp cận nghiên cứu kỹ thuật phân tích chương trình tĩnh ở mức mã nguồn, đó là phân tích dựa trên phân tích luồng dữ liệu. Từ các kết quả thu được từ kỹ thuật phân tích này giúp cho việc phân tích các thuộc tính/hành vi có thể xảy ra trong chương trình. Cuối cùng, luận văn tiến hành thực nghiệm kỹ thuật phân tích tĩnh trên công cụ mã nguồn mở SOOT, sử dụng phân tích cho ngôn ngữ lập trình Java.
Tuy nhiên, việc phân tích tĩnh là rất khó và việc phân tích tĩnh dựa trên phân tích luồng dữ liệu là một kỹ thuật được đề cập trong khuôn khổ luận văn tốt nghiệp này. Trong tương lai, một số vấn đề cần tiếp tục nghiên cứu đó là phân tích khoảng, phân tích luồng điều khiển (phân tích con trỏ) và phát triển công cụ phân tích chương trình tĩnh cho các ngôn ngữ khác như C, C++, Java,...nhằm tối ưu hóa chương trình dịch, giảm chi phí và nâng cao chất lượng phần mềm.