KLEE [4, 11]được biết đến như là một công cụ thực thi tượng trưng mới có nhiều cải tiến so với các công cụ kiểm chứng dựa trên thực thi tượng trưng trước đây. Với khả năng tự động tạo ra các ca kiểm thử đảm bảo được độ bao phủ mã nguồn cao trên một môi trường cụ thể .
Có khá nhiều lỗi khác nhau có thể kể đến như lỗi hàm hay lỗi chức năng và khó có thể chỉ ra những lỗi này mà không thực thi toàn bộ hoặc một phần mã nguồn. Cùng với đó, cách tiếp cận bằng việc chọn ngẫu nhiên các giá trị đầu vào hoặc trên một vài giá trị cụ thể nào đó cũng mang lại khó khăn không kém.
Để đạt được kết quả tốt hơn trong trong quá trình sinh ca kiểm thử tự động thay vì thực thi chương trình trên một đầu vào được gán một giá trị cụ thể, hoặc một giá trị ngẫu nhiên trước khi thực thi chương trình. Trong KLEE mã nguồn được thực thi trên một giá trị tượng trưng cho phép nó nhận một giá trị bất kỳ trong suốt quá trình thực thi chương trình.
Giá trị tượng trưng sẽ thay thế cho một giá trị cụ thể cố định. Khi chương trình thực thi với các giá trị tượng trưng thay vì chỉ đi theo một nhánh nhất định tùy thuộc vào giá trị cụ thể được đưa vào. Theo lý thuyết hệ thống sẽ thực hiện trên tất cả các nhánh có thể có, trên mỗi nhánh này duy trì một tập các ràng buộc được gọi là điều kiện rẽ nhánh (path condition). Khi kết thúc một đường thực thi gặp câu lệnh return hoặc gặp lỗi, một ca kiểm thử sẽ được sinh ra bằng cách giải một tập ràng buộc trên đường thực thi hiện tại.
Việc sử dụng đầu vào tượng trưng giúp đảm bảo độ bao phủ mã nguồn cao và phát hiện được nhiều lỗi. Đây cũng là điều mà nhiều công cụ sinh ca kiểm thử tự động hướng tới. Tuy nhiên khi sử dụng đầu vào tượng trưng thường xảy ra hai vấn đề rất đáng quan tâm sau:
1.Số lượng đường thực thi tăng lên theo cấp số nhân dẫn đến sự bùng nổ, đặc biệt khi tiến hành trên các chương trình lớn trong thực tế.
2.Những thách thức phát sinh khi mã thực thi có tương tác với môi trường quanh nó (chẳng hạn như hệ điều hành, mạng, ...) được gọi chung là vấn đề môi trường.
Hình 4.1 Kiến trúc tổng quan của KLEE
Sau khi tiến hành thực thi tượng trưng và thực hiện các bước tối ưu cần thiết. Các ràng buộc trên các đường thực thi tương ứng sẽ được đưa vào SMT solver để giải. Một trong những thách thức chính trong việc xây dựng các công
KLEE Constraint Independence Branch Cache Counter Example Cache LLVM Complier Code C/C++ LLVM Bitcode Symbolic Environment Test case Assignment STP Z3 Boolector MetaSMT
cụ thực thi tượng trưng là việc quyết định chọn ra một solver tốt nhất, hiệu quả và phù hợp nhất. Tuy nhiên, mỗi SMT solver lại có một thế mạnh riêng. Đối với nhiều truy vấn khác nhau không thể khẳng định rằng truy vấn nào thực hiện tốt nhất. Chính vì vậy, mà KLEE tích hợp 3 SMT solver để tận dụng thế mạnh của các SMT khác nhau. Cụ thể, đó là ba SMT solver được đánh giá là hiệu quả STP [26], Z3 [15], Boolector [21].
Để có cái nhìn tổng quan về kiến trúc và cách thức hoạt động của KLEE xem hình 4.1. Từng thành phần trong kiến trúc của KLEE tại hình 4.1 sẽ được trình bày trong phần tiếp theo.