JPF [15,16] là một máy ảo Java (JVM) được sử dụng để phát hiện lỗi (bugs) trong các chương trình Java. Có thể sử dụng JPF một cách linh hoạt dưới dạng giao diện dòng lệnh hoặc tích hợp vào trong các môi trường phát triển ứng dụng Java như Netbean, Eclipse. JPF là một ứng dụng Java mã nguồn mở cho phép ta cấu hình để sử dụng nó theo các cách khác nhau và mở rộng nó.
JPF được thiết kế xung quanh hai khái niệm trừu tượng chính: JPF được thiết kế gồm hai thành phần chính đó là: đối tượng máy ảo (JVM) và đối tượng tìm kiếm (Search Object).
Hình 3.1: Kiến trúc JPF
Máy ảo (JVM):
Máy ảo JVM của JPF là một bộ sinh trạng thái bằng việc thực thi các chỉ thị bytecode, nó có khả năng quản lý các trạng thái: quay lui, khớp trạng thái và máy ảo lưu trữ trạng thái. Có 3 phương thức JVM chính hợp tác giữa máy ảo và tìm kiếm (VM-Search):
18
forward() – sinh trạng thái tiếp theo, thông báo nếu trạng thái sinh ra là nút lá. Nếu đúng lưu trữ vào một ngăn xếp backtrack phục vụ phục hồi hiệu quả.
backtrack() – phục hồi trạng thái cuối trong ngăn xếp quay lui. restoreState() – phục hồi một trạng thái tùy ý.
Máy ảo JPF được cài đặt tuân theo các đặc tả về máy ảo Java nhưng không giống như các máy ảo Java chuẩn khác máy ảo JPF có khả năng lưu trữ trạng thái (state storing), ghi nhớ trạng thái (state matching) và quay lui trong quá trình thực thi chương trình.
Quay lui (backtracking) có nghĩa là JPF có thể phục hồi lại trạng thái thực thi lúc trước để xem có còn những sự lựa chọn thực thi khác.
Ghi nhớ trạng thái (state matching) có nghĩa là đánh dấu các trạng thái đã thám hiểm mà không còn cần thiết nữa giúp JPF tránh được những sự thực thi không cần thiết. Trạng thái thực thi của một chương trình bao gồm heap và ngăn xếp tiến trình. Trong khi thực thi JPF kiểm tra mọi trạng thái mới có phải là các trạng thái đã được ghi nhớ. Nếu các trạng thái đã được ghi nhớ JPF sẽ không tiếp tục đi theo đường đi thực thi hiện hành và quay lui tới trạng thái gần nhất mà chưa được thám hiểm.
Đối tƣợng tìm kiếm (Search Object): là một cấu hình chiến lược tìm kiếm
đối tượng theo hướng thực thi trong máy ảo. Nói cách khác, đối tượng tìm kiếm lựa chọn các trạng thái mà từ đó JVM nên xử lý bằng cách trực tiếp JVM sinh ra trạng thái tiếp theo hoặc quay lại trạng thái được tạo ra trước đó. Một khả năng quan trọng của đối tượng tìm kiếm là nó có thể đánh giá đối tượng thuộc tính, chẳng hạn như: xác định một thuộc tính là không phải deadlock - phương thức
NotDeadlocked, hoặc đảm bảo rằng các thuộc tính không vi phạm sự khẳng định. – phương thức NoAssertionsViolatedProperty.
Search Object là bộ điều khiển của VM. Search Object điều khiển việc thực thi trong JVM. Search Object chịu trách nhiệm chọn lựa trạng thái để VM tiếp tục quá trình thực thi bằng việc điều khiển VM để sinh ra trạng thái tiếp theo (foward) hoặc quay lui về trạng thái đã được tạo lúc trước. Theo mặc định, kỹ thuật tìm kiếm theo chiều sâu được sử dụng. Một kỹ thuật tìm kiếm dựa trên hàng đợi ưu tiên (tìm kiếm kinh nghiệm) cũng được cài đặt và ta có thể cấu hình để sử dụng nó. Phương thức tìm kiếm được cài đặt với một vòng lặp và chỉ dừng lại khi không gian trạng thái đã được thám hiểm hết hoặc tìm ra một sự vi phạm.
19
Với những chương trình lớn và phức tạp thì không gian trạng thái trong quá trình thực thi chương trình là rất lớn. Việc lưu trữ và thám hiểm tất cả các trạng thái không phải lúc nào cũng đạt được. JPF sử dụng các kỹ thuật khác nhau để giải quyết vấn đề này đó là các chiến lược tìm kiếm, các kỹ thuật để giảm thiểu số trạng thái chương trình và việc lưu trữ các trạng thái. Có các chiến lược tìm kiếm khác nhau được sử dụng như tìm kiếm theo chiều sâu (Depth-First Search), theo chiều rộng (Breadth-First Search), tìm kiếm kinh nghiệm.