1. Trang chủ
  2. » Luận Văn - Báo Cáo

Kỹ thuật phân tích chương trình tĩnh cho bài toán phân tích hình dạng bộ nhớ heap

61 515 1

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 61
Dung lượng 2,34 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Trong chương này trình bày định nghĩa kỹ thuật phân tích chương trình tĩnh, ứng dụng, điểm mạnh và điểm yếu của kỹ thuật này.. Phân tích luồng dữ liệu là một kỹ thuật thu thập thông tin

Trang 1

TRƯỜNG ĐẠI HỌC CÔNG NGHỆ

NGUYỄN QUANG ĐẠI

KỸ THUẬT PHÂN TÍCH CHƯƠNG TRÌNH TĨNH CHO BÀI TOÁN PHÂN TÍCH HÌNH DẠNG BỘ NHỚ

HEAP

LUẬN VĂN THẠC SĨ CÔNG NGHỆ THÔNG TIN

Hà Nội – 2015

Trang 2

TRƯỜNG ĐẠI HỌC CÔNG NGHỆ

NGUYỄN QUANG ĐẠI

KỸ THUẬT PHÂN TÍCH CHƯƠNG TRÌNH TĨNH CHO BÀI TOÁN PHÂN TÍCH HÌNH DẠNG BỘ NHỚ

HEAP

Ngành: Công nghệ thông tin

Chuyên ngành: Kỹ thuật phần mềm

Mã số: 60480103

LUẬN VĂN THẠC SĨ CÔNG NGHỆ THÔNG TIN

NGƯỜI HƯỚNG DẪN KHOA HỌC: TS Nguyễn Trường Thắng

Hà Nội - 2015

Trang 3

Tôi xin cam đoan rằng đây là công trình nghiên cứu của tôi trong đó có sự giúp đỡ của Thầy giáo hướng dẫn và các đồng nghiệp tại cơ quan Các nội dung

và kết quả nghiên cứu trong luận văn này là hoàn toàn trung thực

Trong luận văn, tôi có tham khảo đến một số tài liệu của một số tác giả được liệt kê tại mục tài liệu tham khảo

Hà Nội, 03 tháng 07 năm 2015

Học viên

Nguyễn Quang Đại

Trang 4

Tôi xin chân thành cảm ơn các thầy cô giáo trong Khoa Công nghệ Thông tin, Trường Đại học Công nghệ – Đại học Quốc gia Hà Nội đã tận tình giảng dạy trang bị cho tôi kiến thức, giúp tôi hoàn thành luận văn

Tôi cũng xin được bày tỏ lòng kính trọng và lời cảm ơn sâu sắc nhất tới TS Nguyễn Trường Thắng, Phó Viện trưởng, Viện Công nghệ Thông Tin – Viện Hàn lâm Khoa học và Công nghệ Việt Nam Thầy đã luôn động viên và hướng dẫn tôi hoàn thành luận văn tốt nghiệp

Mặc dù đã cố gắng để hoàn thành luận văn, nhưng trong phạm vi và khả năng cho phép không thể tránh khỏi những thiếu sót, mong nhận được sự cảm thông và tận tình chỉ bảo của các thầy cô

Hà Nội, 03 tháng 07 năm 2015

Học viên

Nguyễn Quang Đại

Trang 5

MỤC LỤC

MỤC LỤC 1

DANH MỤC CÁC KÝ HIỆU VÀ CHỮ VIẾT TẮT 3

DANH SÁCH HÌNH VẼ 4

MỞ ĐẦU 5

CHƯƠNG 1 GIỚI THIỆU CHUNG 7

1.1 Đặt vấn đề 7

1.2 Giới thiệu phân tích chương trình tĩnh 7

1.3 Điểm mạnh và điểm yếu của phân tích chương trình tĩnh 8

1.4 Các kỹ thuật phân tích chương trình tĩnh 8

CHƯƠNG 2 LÝ THUYẾT NỀN TẢNG 11

2.1 Nền tảng phân tích ngữ nghĩa của chương trình 11

2.1.1 Lý thuyết giàn 11

2.1.2 Thuộc tính đóng 13

2.1.3 Phương trình và bất phương trình 15

2.1.4 Lý thuyết điểm cố định 16

2.1.5 Các kỹ thuật tăng tốc độ hội tụ widening/narrowing 18

2.2 Kết luận chương 22

CHƯƠNG 3 PHÂN TÍCH HÌNH DẠNG HEAP 23

3.1 Phân tích con trỏ 23

3.1.1 Thuật toán Andersen 23

3.1.2 Thuật toán Steensgaard 25

3.2 Phân tích con trỏ liên thủ tục 26

3.3 Phân tích hình dạng bộ nhớ heap 27

3.2.1 Kỹ thuật phân tích 29

3.2.2 Đánh giá 33

3.3 Kết luận chương 33

CHƯƠNG 4 THỰC NGHIỆM 34

Trang 6

4.1 Tổng quan về Valgrind 34

4.1.1 Công cụ Memcheck 35

4.1.2 Biên dịch chương trình với Memcheck 37

4.1.3 Lệnh kiểm tra trong Memcheck 37

4.2 Phân tích heap của chương trình trong Valgrind 39

4.2.1 Rò rỉ bộ nhớ 39

4.2.2 Sử dụng bộ nhớ không được khởi tạo 40

4.2.3 Lỗi sử dụng không đúng giữa malloc/ new/ new[] với free/ delete/ delete[] 43

4.2.4 Thực nghiệm trên chương trình có mã nguồn lớn 45

KẾT LUẬN 47

TÀI LIỆU THAM KHẢO 48

PHỤ LỤC A 49

PHỤ LỤC B 51

PHỤ LỤC C 55

Trang 7

DANH MỤC CÁC KÝ HIỆU VÀ CHỮ VIẾT TẮT

Trang 8

DANH SÁCH HÌNH VẼ

Hình 2.1 Biểu đồ Hasse biểu diễn giàn 11

Hình 2.2 Quan hệ thứ tự từng phần là giàn 12

Hình 2.3 Quan hệ thứ tự từng phần không phải giàn 12

Hình 2.4 Ví dụ giàn có chiều cao là 4 13

Hình 2.5 Phép toán cộng giàn 14

Hình 2.6 Phép toán nâng (lift) giàn 14

Hình 2.7 Phép toán lift của các tập tạo thành giàn 14

Hình 2.8 Tính toán điểm cố định trên giàn 17

Hình 2.9 Giàn có chiều cao vô hạn 19

Hình 3.1 Quan hệ tương đương giữa các ràng buộc 26

Hình 3.2 Đồ thị heap 30

Hình 3.3 Đồ thị hình dạng heap sau vòng lặp 32

Hình 4.1 Kết quả ví dụ rò rỉ bộ nhớ trong Memcheck 40

Hình 4.2 Kết quả ví dụ sử dụng bộ nhớ chưa được khởi tạo trong Memcheck sử dụng –track-origins 42

Hình 4.3 Kết quả ví dụ sử dụng bộ nhớ chưa được khởi tạo trong Memcheck không sử dụng –track-origins 43

Hình 4.4 Kết quả ví dụ lỗi sử dụng không đúng giữa malloc/new/new[] với free/delete/delete[] 44

Trang 9

MỞ ĐẦU

Ngày nay với sự phát triển vượt bậc của công nghệ thông tin, thì phần mềm

có vai trò cốt lõi và ngày càng chiếm vị trí quan trọng không những trong công nghệ thông tin mà còn trong đời sống kinh tế xã hội Vấn đề chất lượng phần

mềm (software quality) chắc chắn là mối quan tâm và thách thức đối với xã hội

hiện đại ngày càng phụ thuộc vào các dịch vụ do máy tính đem lại này

Liên quan tới đảm bảo chất lượng phần mềm, khía cạnh quản lý bộ nhớ cũng rất được quan tâm Quản lý bộ nhớ được chia làm hai giai đoạn chính là phân bổ

bộ nhớ theo yêu cầu, và giải phóng khi chương trình không còn sử dụng Hiện nay, nhiều hệ thống ngôn ngữ lập trình sử dụng cơ chế quản lý bộ nhớ tự động, tiêu biểu như Java và C# Trong Java, người lập trình không cần phải chú trọng đến phân bổ và giải phóng bộ nhớ Khi khối bộ nhớ được phân bổ không còn

được sử dụng máy ảo Java (Java Virtual Machine) sẽ tự giải phóng bộ nhớ thông qua cơ chế thu dọn rác tự động (Automatic Garbage Collection) [1] Thu

gom rác tự động là quá trình kiểm tra bộ nhớ heap, xác định những đối tượng đang được sử dụng và không được sử dụng, và xóa những đối tượng không được

sử dụng Chức năng cơ bản của GC (Garbage Collection) là gồm hai bước trừu

tượng (trong thực tế hai pha này có thế đan xen nhau):

 Phát hiện rác (tìm đối tượng từ đống rác bằng một cách nào đó)

 Cải tạo rác (Cải tạo lại ô nhớ của đối tượng rác, khi đó chương trình đang chạy có thể sử dụng ô nhớ này)

Tuy nhiên, một số ngôn ngữ lập trình truyền thống, được sử dụng phổ biến trong thực tế như C, C++ thì vấn đề quản lý bộ nhớ vẫn được đặt hoàn toàn vào lập trình viên [6] Lập trình viên tự động cấp phát bộ nhớ, nhưng khi một khối không còn cần thiết, họ cần phải trả lại cho hệ thống bằng lời gọi hàm hệ thống

như free() Hậu quả là nếu người lập trình quên hoàn trả các vùng đã cấp phát về

cho bộ nhớ và lại tiếp tục dùng các lệnh cấp phát, thì càng lúc càng nhiều các phần của bộ nhớ bị chiếm chỗ Điều này có thể dẫn tới các lỗi liên quan tới bộ nhớ, đặc biệt là khối bộ nhớ khởi tạo tự động bởi con trỏ hay mắc lỗi rò rỉ bộ

nhớ (memory leak) Quản lý bộ nhớ là quan trọng và có nhiều khía cạnh nghiên

cứu Các kỹ thuật thu dọn rác là một hướng tiếp cận của vấn đề này

Mục tiêu của luận văn này là tìm hiểu về kỹ thuật phân tích chương trình tĩnh, cập nhật những xu hướng nghiên cứu trong và ngoài nước về lĩnh vực phân tích chương trình tĩnh, và cải tiến những kỹ thuật này Cụ thể, luận văn tập trung vào hướng tiếp cận là tìm hiểu kỹ thuật phân tích hình dạng bộ nhớ heap của

Trang 10

chương trình Kết quả của kỹ thuật có thể áp dụng trong khâu loại bỏ các đối tượng là rác Kỹ thuật dựa trên lý thuyết ngữ nghĩa chương trình theo các con trỏ Lý thuyết giàn, ngữ nghĩa điểm cố định cũng sẽ được sử dụng như nền tảng của kỹ thuật này

Luận văn có cấu trúc như sau:

Chương 1 giới thiệu tổng quan về phân tích chương trình tĩnh Trong chương này trình bày định nghĩa kỹ thuật phân tích chương trình tĩnh, ứng dụng, điểm mạnh và điểm yếu của kỹ thuật này Tiếp đó luận văn trình bày một vài kỹ thuật phân tích chương trình tĩnh phổ biến hiện nay, bài toán và kỹ thuật mà luận văn thực hiện tìm hiểu

Chương 2 trình bày nền tảng ngữ nghĩa của một chương trình

Chương 3 trình bày về kỹ thuật phân tích hình dạng bộ nhớ heap Đưa ra các bài toán, cách giải quyết và đánh giá

Chương 4 thực nghiệm với công cụ Valgrind

Cuối cùng là phần kết luận và tài liệu tham khảo

Trang 11

CHƯƠNG 1 GIỚI THIỆU CHUNG

1.1 Đặt vấn đề

Với sự tiến bộ nhanh chóng của cách mạng công nghệ thông tin và chất liệu chính là phần mềm Nếu như trước đây phần mềm máy tính chỉ được sử dụng để tính toán khoa học kỹ thuật và xử lý dữ liệu thì ngày nay nó đã được ứng dụng vào mọi mặt của đời sống hàng ngày của con người Vì thế con người ngày càng phụ thuộc chặt chẽ vào các sản phẩm phần mềm và do vậy đòi hỏi về chất lượng của các sản phẩm phần mềm ngày càng cao, tức là phần mềm phải được sản xuất với giá thành thấp, dễ dùng, an toàn và tin cậy được Đánh giá chất lượng phần mềm thông thường qua các hoạt động phổ biến như tìm xem phần mềm có lỗi không và có những kỹ thuật nào để phát hiện các lỗi đó

Việc phát hiện lỗi hay bất cứ vấn đề gì về sản phẩm đều có thể thực hiện ở các mức của quá trình sản xuất phần mềm như mức phân tích, mức thiết kế và mức lập trình Ở mức lập trình việc phát hiện lỗi trở nên phức tạp và khó giải quyết hơn Cụ thể như bài toán quản lý bộ nhớ Hiện nay, nhiều hệ thống ngôn ngữ lập trình sử dụng cơ chế quản lý bộ nhớ tự động, tiêu biểu như Java và C# Tuy nhiên, một số ngôn ngữ lập trình truyền thống, được sử dụng phổ biến trong thực tế như C, C++ thì vấn đề quản lý bộ nhớ vẫn được dựa hoàn toàn vào lập trình viên Liên quan tới bài toán này kỹ thuật phân tích chương trình tĩnh của mảng các kỹ thuật kiểm chứng chương trình là có tính ứng dụng và hiệu quả cao Và việc áp dụng kỹ thuật phân tích chương trình tĩnh vào trong bài toán quản lý bộ nhớ sẽ là nội dung chính của luận văn này

1.2 Giới thiệu phân tích chương trình tĩnh

Phân tích chương trình tĩnh là kỹ thuật xác định tính chất/ hành vi của một chương trình mà không cần phải chạy chương trình đó Có rất nhiều câu hỏi thú

vị liên quan tới chương trình hoặc các điểm (point) riêng lẻ trong chương trình:

 Chương trình có dừng hay không?

 Độ lớn có thể của vùng nhớ heap trong quá trình chạy như thế nào?

Đầu ra (output) có thể là gì?

 Giá trị của sẽ được đọc trong tương lai?

 Điểm và có cấu trúc tách rời nhau trong heap?

 Con trỏ có thể null?

 Biến đã được khởi tạo trước đọc hay không?

 v.v

Trang 12

Theo lý thuyết Rice [9], tất cả các câu hỏi liên quan tới hành vi chương trình

là không quyết định được (undecidable) Việc xử lý vấn đề này luôn đi kèm một

số kĩ thuật xấp xỉ nhằm đưa về bài toán giải được hoặc để tối ưu hóa kết quả Thay vì mức mô hình như nhiều phương pháp hình thức, luận văn hướng tới việc phân tích chương trình tĩnh Cụ thể luận văn sẽ đi sâu tìm hiểu về một bài toán đặc trưng trong phân tích chương trình tĩnh và các hướng giải quyết của bài toán đó

1.3 Điểm mạnh và điểm yếu của phân tích chương trình tĩnh

Phân tích chương trình tĩnh có một số ưu điểm sau:

 Chỉ ra được chính xác vị trí lỗi trong chương trình

 Lỗi được phát hiện sớm trong quy trình phát triển phần mềm nên chi phí sửa thấp

 Tự động hóa nhanh: thông qua các công cụ hỗ trợ như TVLA, Astree, SOOT, Valgrind …

 Dễ dàng thực hiện bởi những chuyên gia kiểm định chất lượng phần mềm hiểu rõ về mã nguồn

Tuy nhiên, điểm yếu của kỹ thuật này xuất hiện khi tại một câu lệnh xuất hiện những tham chiếu, ràng buộc nằm ngoài phạm vi suy luận biểu trưng của chương trình Hạn chế này là bản chất của việc phân tích tĩnh - không chạy với

dữ liệu cụ thể Một số điểm yếu không khắc phục được:

 Không phát hiện được lỗi chỉ xuất hiện khi chạy chương time error)

trình(run- Mất thời gian nếu thực hiện bằng tay

 Việc tự động hóa chỉ hướng vào một số ngôn ngữ nhất định

 Đòi hỏi nhân lực phải có kiến thức về ngôn ngữ lập trình

 Có thể sinh ra nhiều lời cảnh báo lỗi không chính xác

1.4 Các kỹ thuật phân tích chương trình tĩnh

Những kỹ thuật phân tích chương trình tĩnh đã và đang thu hút nhiều nghiên cứu trên thế giới, hiện có nhiều kỹ thuật nhưng tựu chung có thể phân theo 4 nhóm chính như sau:

Thứ nhất, kỹ thuật phân tích chương trình tĩnh dựa trên phân tích luồng dữ

liệu (data flow analysis) [8] [10] Phân tích luồng dữ liệu là một kỹ thuật thu

thập thông tin về tập các giá trị được tính toán có thể có tại các điểm khác nhau của chương trình Thông tin thu được thường được trình biên dịch sử dụng để tối

Trang 13

ưu hóa chương trình Phân tích luồng dữ liệu là một cách rất hiệu quả và khả thi trong việc phát hiện lỗi chương trình và tối ưu hóa trong các trình biên dịch Cách đơn giản để phân tích luồng dữ liệu là thiết lập phương trình luồng dữ liệu

cho mỗi nút của đồ thị luồng dữ liệu (DFG – data flow graph) và sử dụng thuật

toán điểm cố định để giải hệ phương trình này Và một số ứng dụng phổ biển

của phân tích luồng dữ liệu là phân tích tính tới được (reaching definitions), biểu thức có sẵn (available expressions), biểu thức bận rộn (very busy expressions)

và phân tích tính sống (liveness analysis) [10]

Thứ hai, nhóm kỹ thuật liên quan tới xấp xỉ ngữ nghĩa được gọi là diễn giải

trừu tượng (abstract interpretation) [2] [3] Kỹ thuật diễn giải trừu tượng dựa

trên nguyên tắc xấp xỉ ngữ nghĩa của chương trình khi kiểm tra đối chiếu sự thỏa

mãn đặc tả Kỹ thuật này trích ra từ một ngữ nghĩa chuẩn (standard semantics) được một ngữ nghĩa trừu tượng đã xấp xỉ và tính toán được (approximate and

computable abstract semantics) Quá trình chuyển này không hoàn toàn tự động

mà có thể cần sự tương tác với người dùng để tinh chỉnh (refinement) các ánh xạ

trừu tượng thông qua các tham số đưa vào, bởi vì có thể đầu tiên tạo ra (là ngữ nghĩa trừu tượng từ chương trình ) không thỏa mãn đặc tả , trước hết phải tinh chỉnh chứ không kết luận ngay là không thỏa mãn do tính không

hoàn chỉnh (incompleteness) của kỹ thuật diễn giải trừu tượng Thay vì kiểm

chứng đặc tả trên , chúng ta kiểm chứng đối với ngữ nghĩa trừu tượng của Nếu thỏa mãn bởi , do tính đúng đắn của kỹ thuật diễn giải trừu tượng, đương nhiên thỏa mãn Tính ưu việt của kỹ thuật này là độ phức tạp của nhỏ hơn rất nhiều tùy theo quá trình trừu tượng hóa (ánh xạ trừu tượng hóa từ vào ) như thế nào Trong thực tế, kỹ thuật diễn giải trừu tượng có

một thành phần là bộ sinh (generator) ngữ nghĩa trừu tượng đọc mã nguồn

chương trình và tạo ra các ràng buộc hoặc hệ các phương trình cần được giải bởi

máy tính thông qua một thành phần khác là bộ giải (solver) Một phương pháp

phổ biến là dùng hàm lặp khi giải Việc tìm nghiệm thông qua hàm lặp có hạn chế về mặt thời gian (phương pháp không hội tụ sau vô hạn lần lặp) Các kỹ thuật liên quan tới việc tăng tốc hội tụ cũng được nghiên cứu

Thứ ba, nhóm kỹ thuật liên quan tới mô hình được gọi là kỹ thuật kiểm

chứng mô hình (Model checking) [5] Kiểm chứng mô hình là kỹ thuật kiểm tra

xem một mô hình của hệ thống có thỏa mãn một tính chất nào đó hay không Cụ thể hơn, với mô hình và thuộc tính cho trước, kỹ thuật kiểm tra xem thuộc tính có thỏa mãn trong mô hình hay không: Về mặt thực thi, kiểm chứng mô hình là kỹ thuật tĩnh, nó duyệt qua tất cả các trạng thái, các đường

Trang 14

thực thi có thể có trong mô hình để xác định tính khả thỏa của Nếu một hệ thống không thoả mãn một tính chất thì kiểm chứng mô hình sẽ đưa ra phản ví

dụ với một chuỗi các trạng thái và sự kiện liên quan bắt đầu từ trạng thái ban đầu tới trạng thái lỗi của mô hình Những tính chất kiểm tra thường là tính sống

(liveness properties), tính an toàn (safety properties) như khả năng không tồn tại khóa chết (deadlock) hoặc rơi vào những trạng thái nguy hiểm tạo sự cố cho hệ

thống Nhóm kỹ thuật này tập trung vào các hệ thống hữu hạn trạng thái hoặc

được giảm xuống còn hữu hạn trạng thái bởi sự trừu tượng hóa (abstraction) Cuối cùng, kỹ thuật phân tích biểu trưng (symbolic analysis) [14] Kỹ thuật

này là phân tích tĩnh mã nguồn tĩnh, xây dựng các luồng rẽ nhánh trong chương trình dựa trên các nút Tại các nút tương ứng sẽ là tập hợp các ràng buộc

(constraints) của dữ liệu, biến, tham số Tại nút khởi tạo chương trình, tập hợp

các ràng buộc là rỗng Càng đi sâu xuống các nhánh nhỏ, tại các nút con, tập hợp ràng buộc sẽ được tạo ra từ tập hợp ràng buộc tại nút ngay phía trên cộng với điều kiện giữa các biến số để có thể rẽ từ nút trên vào nút dưới trong luồng chảy chương trình Điểm đặc biệt của kỹ thuật này là các tham số hoàn toàn được thể hiện bằng ký tự biểu trưng, chứ không phải giá trị cụ thể Ý tưởng của phương pháp này là để kiểm thử một nhánh trong chương trình, điều kiện tiên quyết là dữ liệu tại đầu vào phải thỏa mãn tập hợp các ràng buộc tại nút bắt đầu nhánh đó Việc giải các ràng buộc gắn với một nút được thực hiện bởi các bộ

công cụ sẵn có gọi là giải ràng buộc (constraint solver) dựa trên SMT (Satisfiability Modulo Theories) hay SAT (Satisfiability Testing)

Hai nhóm đầu tập trung vào việc nâng cao chất lượng phần mềm tại mức mã nguồn, trong khi hai nhóm sau xử lý phần mềm tại mức trừu tượng cao hơn –

mô hình

Với tình hình nghiên cứu cơ bản và xu thế công nghệ phần mềm trên thế giới hiện nay tập trung vào các vấn đề lớn như quy mô và chất lượng của các sản phẩm phần mềm, bài toán quản lý bộ nhớ heap là một trong những bài toán phổ biến đặc trưng trong đảm bảo chất lượng phần mềm Việc tiến hành nghiên cứu trong lĩnh vực này là cần thiết trong việc nâng cao chất lượng nghiên cứu ứng dụng vào thực tế kiểm soát chất lượng phần Do đó, luận văn sẽ tập trung vào nhóm các kỹ thuật liên quan để giải quyết bài toán trên

Trang 15

CHƯƠNG 2 LÝ THUYẾT NỀN TẢNG

2.1 Nền tảng phân tích ngữ nghĩa của chương trình

2.1.1 Lý thuyết giàn

Trong kỹ thuật phân tích chương trình tĩnh của luận văn, các phân tích sử

dụng cấu trúc toán học là Giàn (Lattices) [10], tập các thuộc tính (ví dụ: tập các

biến, biểu thức trong chương trình) cần thiết cho mỗi phân tích tĩnh trong chương trình

Một thứ tự bộ phận (Partial order) là một cấu trúc toán học: , trong đó là một tập hợp và là một quan hệ 2 ngôi trên thỏa mãn các điều kiện sau:

 Phản xạ:

 Bắc cầu:

 Phản đối xứng:

Biểu diễn giàn thông qua biểu đồ Hasse

Cho giàn là tập có thứ tự bộ phận, biểu đồ Hasse của giàn L bao gồm :

 Một tập hợp các điểm trong mặt phẳng tương ứng 1-1 với S, gọi là các đỉnh

 Một tập hợp các cung nối một số cặp đỉnh có quan hệ thứ tự bộ phận

Ví dụ, biểu diễn giàn { } (như hình) hoặc giàn đảo ngược (Giàn được sắp xếp bởi thứ tự ngược của các tập con và quan hệ hai ngôi được định nghĩa là ) { } bằng biểu đồ Hasse :

Hình 2.1 Biểu đồ Hasse biểu diễn giàn

Trang 16

Cho , khi đó được gọi là một cận trên của , kí hiệu là , nếu Tương tự được gọi là một cận dưới của , kí hiệu là , nếu Cận trên nhỏ nhất của kí hiệu là , được định nghĩa như sau:

Tương tự, cận dưới lớn nhất, kí hiệu là , được định nghĩa như sau:

Giàn (Lattice) là một quan hệ thứ tự từng phần mà trong đó và tồn

tại đối với tất cả Lưu ý rằng một giàn có duy nhất một phần tử lớn nhất được định nghĩa là = S và duy nhất một phần tử nhỏ nhất được định nghĩa là

Khi xem xét các giàn hữu hạn, yêu cầu ít nhất là tồn tại phần tử lớn nhất và nhỏ nhất và với mỗi cặp phần tử x và y có một cận trên nhỏ nhất kí hiệu là

và cận dưới nhất nhất kí hiệu là

Một quan hệ thứ tự từng phần hữu hạn được minh họa bởi một biểu đồ trong

đó các phần tử là các nút và quan hệ thứ tự là quan hệ bao đóng bắc cầu

(transitive closure) các cạnh từ nút thấp lên nút cao hơn Với cách biểu diễn này

các quan hệ thứ tự trong Hình 2.2 đều là giàn

Hình 2.2 Quan hệ thứ tự từng phần là giàn

Trong khi các quan hệ thứ tự trong hình 2.3 không phải là giàn

Hình 2.3 Quan hệ thứ tự từng phần không phải giàn

Ví dụ mỗi tập hợp hữu hạn phần tử A định nghĩa một giàn , trong đó

Trang 17

Hình 2.4 Ví dụ giàn có chiều cao là 4

2.1.2 Thuộc tính đóng

Nếu là những giàn với độ cao hữu hạn, từ đó một phép toán

tích (product):

{ } với được định nghĩa là theo từng điểm (point-wise) Với chú ý rằng và có thể được tính toán theo từng điểm và như vậy

Tương tự ta có, một phép toán cộng (sum):

{ { }} { } với và được cho trước và khi và chỉ khi và Chú ý rằng { } Phép toán cộng được minh như sau:

Trang 18

Hình 2.5 Phép toán cộng giàn

Nếu giàn là một giàn với độ cao hữu hạn, khi đó , độ cao của giàn là: , minh họa nhƣ sau:

Hình 2.6 Phép toán nâng (lift) giàn

Nếu là một tập hữu hạn ( không cần thiết phải là một giàn), khi đó đƣợc minh họa bởi

Hình 2.7 Phép toán lift của các tập tạo thành giàn

Trang 19

Và là một giàn có độ cao là 2

Cuối cùng, nếu và được định nghĩa như trên, khi đó chúng ta thu được

một giàn ánh xạ (map) với độ cao như sau:

{ } theo từng điểm thứ tự: Nếu là hữu hạn và

có độ cao hữu hạn khi đó

2.1.3 Phương trình và bất phương trình

Trong phân tích mã nguồn chương trình, lý thuyết giàn ngữ nghĩa được sử

dụng Từng nút trong mã nguồn sẽ được gắn một giá trị ngữ nghĩa (semantic)

Ngữ nghĩa của một nút chịu sự ràng buộc trong mối quan hệ với các nút ở trước

và sau nó trong mã nguồn chương trình tùy theo ngữ nghĩa của các câu lệnh đối

với một thuộc tính cần xem xét Ví dụ, thuộc tính con trỏ (shape) trong báo cáo

này Những mối quan hệ ràng buộc thể hiện là các hàm (hàm chuyển đổi ngữ

nghĩa - semantic transformer [4])

Cho là một giàn với độ cao hữu hạn Một hệ phương trình được biểu diễn:

với là những biến và là một tập những hàm đơn điệu Mỗi hệ chỉ

có nghiệm nhỏ nhất duy nhất, nghiệm đó được gọi là điểm cố định nhỏ nhất của hàm được định nghĩa bởi:

Tương tự, có thể giải hệ các bất phương trình:

mặt khác, ta có quan hệ x y tương đương với x = x y.Vì vậy, các nghiệm được duy trì bằng cách viết lại thành hệ phương trình như sau:

Trang 20

đây là một hệ phương trình với các hàm đơn điệu

2.1.4 Lý thuyết điểm cố định

Hàm là đơn điệu khi Lưu ý hợp của hai hàm đơn điệu là một hàm đơn điệu [10]

Lý thuyết về điểm cố định như sau: trong một giàn có chiều cao hữu hạn,

mỗi hàm đơn điệu f có duy nhất một điểm cố định nhỏ nhất (least fixed-point)

định nghĩa như sau:

thỏa mãn Chứng minh lý thuyết này như sau Ta có

do là phần tử nhỏ nhất Do f là hàm đơn điệu nên và bằng phép quy nạp ta có Do đó, ta có chuỗi tăng dần:

Do được giả định là có chiều cao hữu hạn nên sẽ tồn tại mà Chúng ta định nghĩa và từ , chúng ta thấy là một điểm cố định Bây giờ giả

sử rằng là một điểm cố định khác Từ dẫn đến , vì f

là hàm đơn điệu và bằng quy nạp ta có Do đó, là điểm cố định nhỏ nhất Do tính phản đối xứng nên nó là duy nhất

Độ phức tạp tính toán một điểm cố định phụ thuộc vào 3 yếu tố:

 Độ cao của giàn, giá trị độ cao của giàn cung cấp biên cho tham số ;

 Chi phí tính toán của hàm ;

 Chi phí so sánh kết quả có bằng nhau sau mỗi bước lặp

Tính toán một điểm cố định có thể được minh họa bằng các bước đi lên trong một giàn bắt đầu từ điểm (Hình 2.8)

Trang 21

Hình 2.8 Tính toán điểm cố định trên giàn

Ngữ nghĩa của chương trình cung cấp một mô hình toán học mô tả các hành

vi có thể của chương trình đó

Sau đây, luận văn giới thiệu một số thuật toán tìm điểm cố định:

Thuật toán naive

Thuật toán naive tìm điểm cố định x như sau:

{

}

Thuật toán lặp chaotic Thuật toán lặp chaotic tìm điểm cố định Thuật toán lặp chaotic như sau:

{

;

;

Trang 22

}

Thuật toán work-list

Một thuật toán tìm điểm cố định khác là thuật toán work-list, thuật toán này tránh lãng phí khi các thông tin của tất cả các nút được tính toán lại trong mỗi bước lặp, mặc dù ta có thể biết rằng nó không được thay đổi Trong trường hợp tổng quát, tất cả các biến ⟦ ⟧ đều phụ thuộc vào các biến khác Tuy nhiên, một yêu cầu thực tế của sẽ chỉ đọc giá trị của một số các biến khác Thông tin được biểu diễn như ánh xạ:

với mỗi nút cho ta biết tập con của các nút khác mà ⟦ ⟧ xuất hiện một cách

bất thường (nontrivial) trong vế phải của những phương trình Đó là, là

tập hợp các nút chứa thông tin có thể phụ thuộc vào thông tin của nút Một

thuật toán giải quyết cho vấn đề này được gọi là thuật toán work-list nhằm tính

toán điểm cố định Thuật toán work-list như sau:

}

}

Tập được gọi là work-list với các phép toán add và removeNext cho thêm

và loại bỏ một phần tử Độ phức tạp trường hợp xấu nhất không thay đổi, nhưng trong thực tế thuật toán này giúp tiết kiệm nhiều thời gian

2.1.5 Các kỹ thuật tăng tốc độ hội tụ widening/narrowing

Phân tích khoảng (interval analysis) tính toán cận trên và cận dưới đối với

mỗi biến nguyên đối với tất cả các giá trị có thể có của nó Giàn mô tả một biến đơn được định nghĩa như sau:

{ } Trong đó:

{ }

Trang 23

Là tập các số nguyên mở rộng vô hạn điểm kết thúc và có thứ tự trên các khoảng như sau:

Tương ứng bao gồm các điểm Giàn này sẽ như hình 2.9 sau:

Hình 2.9 Giàn có chiều cao vô hạn

Rõ ràng ta không cần thiết một giàn có chiều cao hữu hạn, vì nó chứa đựng các chuỗi vô hạn như trong ví dụ sau:

Điều này dẫn tới giàn ta sẽ sử dụng cuối cùng, như sau:

Trong đó nút đầu vào ta sử dụng hàm không đổi trả về phần tử T:

⟦ ⟧ Với phép gán ràng buộc:

⟦ ⟧ Với các nút khác có ràng buộc là:

⟦ ⟧

Trang 24

Trong đó tất cả các thao tác trừu được định nghĩa như sau:

Vì giàn có chiều cao vô hạn, vì thế ta không thể sử dụng hàm đơn điệu, khi

đó thuật toán điểm cố định có thể không bao giờ kết thúc Điều này tức là giàn

là chuỗi xấp xỉ:

Không bao giờ hội tụ Thay vì bỏ qua, ta sẽ sử dụng kĩ thuật mở rộng

(widening) đưa ra hàm sao cho chuỗi:

( ) Hội tụ đến một điểm cố định mà lớn hơn mọi và vì thế đại diện

cho thông tin đúng đắn của chương trình Hàm mở rộng w sẽ làm thô (coarsen)

bằng trực giác thông tin một cách cẩn thận để đảm bảo sự kết thúc Với phân

tích khoảng, w được xác định theo từng điểm xuống đến khoảng đơn Nó thực

hiện so sánh với hữu hạn điểm cố định sao ho chưa đựng và Thông thường có thể là tất cả các hằng số xuất hiện trong chương trình, nhưng

kỹ thuật suy nghiệm cũng có thể được sử dụng Trong khoảng đơn ta có:

{ } { }

Là khoảng phù hợp nhất trong số những khoảng được chọn

Widening mở rộng trên các đích, nhưng kỹ thuật sau đây được gọi là

narrowing có thể cải thiện kết quả Nêu ta định nghĩa:

Trang 25

∐ Khi đó ta có Tuy nhiên, ta cũng có , nghĩa là ứng dụng tiếp theo của có thể làm mịn kết quả và vẫn tạp ra thông tin

đúng đắn Kĩ thuật này đƣợc gọi là thu hẹp (narrowing), trên thực tế cso thể lặp

[ ]

Tuy nhiên, kết quả đối với không chính xác Khi đó, có thể dùng

narrowing để tinh chỉnh lại kết quả :

[ ]

Trang 26

Đó là kết quả tốt nhất có thể hi vọng Để thu hẹp hơn nữa là không khả thi Lưu ý rắng chuỗi giảm :

Trang 27

CHƯƠNG 3 PHÂN TÍCH HÌNH DẠNG HEAP

3.1 Phân tích con trỏ

Trong khoa học máy tính, phân tích con trỏ (pointer analysis), hay gọi là

points – to analysis, là kỹ thuật phân tích mã nguồn tĩnh xác định một tập các

đối tượng là các con trỏ, hoặc các tham chiếu heap gọi là các đích, có thể trỏ tới bởi các biến hoặc nơi lưu trữ Một kỹ thuật có liên quan chặt chẽ khác là phân

tích hình dạng (shape analysis)

Tất nhiên có vô hạn đích có thể chọn trong quá trình thực thi, vì vậy ta phải chọn các đại diện hữu hạn Cách chọn kinh điển nhất là tạo một đích cho mọi biến tên và đích malloc – i, với là duy nhất, cho mỗi vị trí được cấp

phát khác nhau (điểm mà chương trình thực hiện thao tác malloc) Sử dụng

Targets để biểu diễn tập tất cả các đích con trỏ của chương trình [10]

Phân tích points – to được thực hiện dựa trên cây phân tích cú pháp Kết quả cuối cùng của phân tích points – to là một hàm mà với mỗi biến (con trỏ)

trả lại một tập của các đích con trỏ mà nó có thể trỏ tới Tất nhiên ta phải thực hiện một phân tích bảo toàn, vì thế các tập này sẽ rất lớn

Với thông tin này, nếu ta muốn biết liệu các biến con trỏ và có thể là các

aliases (cặp con trỏ cùng trỏ tới một nút), khi đó phải thực hiện kiểm tra sao

cho không rỗng

Ta có thể phân tích points – to bằng một số thuật toán Andersen,

Atreengaard

3.1.1 Thuật toán Andersen

Một cách tiếp cận để phân tích points – to khá giống với phân tích luồng điều khiển (Control flow analysis) Với mỗi biến con trỏ ta khởi tạo một tập

biến ⟦ ⟧ là tập tất cả các đích của con trỏ trong chương trình

Phân tích giả sử rằng chương trình đã được chuẩn hóa để mỗi thao tác con trỏ là một trong sáu loại sau:

Trang 28

Với mỗi thao tác con trỏ sinh ra một ràng buộc như sau:

{ } ⟦ ⟧ (với i thể hiện cho các vị trí được cấp phát khác nhau)

gán bằng null, vì nó tương ứng với ràng buộc ⟦ ⟧ Những ràng buộc này

kết hợp với thuật toán Cubic có thể giải trong thời gian Kết quả có hàm

points – to như sau:

⟦ ⟧ Xét ví dụ sau:

Trang 29

3.1.2 Thuật toán Steensgaard

Đây là một phân tích thô về cơ bản bằng cách xem sự việc theo hai hướng

Sử dụng một tập hợp gồm các thẻ malloc – i và hai thẻ có dạng và cho

mỗi biến tên Với chương trình đã chuẩn hóa ở trên, nhưng ở đây sinh ràng buộc tương đương với các thẻ như sau:

Các ràng buộc tạo ra một quan hệ tương đương trên các thẻ, có thể tinh toán

trong thời gian tuyến tính Kết quả hàm points – to như sau:

{ } { }

Sau đó ta có thể tự điều chỉnh những trường hợp xảy ra trong chương trình Nếu chúng ta chỉ xem xét một loại chương trình nhất định, thì có thể tiếp tục loại bỏ các đích con trỏ không phù hợp

Xét ví dụ ở phần 3.1.1 Thuật toán Steengaard sinh ra các ràng buộc sau:

Trang 30

Các ràng buộc này bao gồm một quan hệ tương đương như sau:

Hình 3.1 Quan hệ tương đương giữa các ràng buộc

Ta thấy trường hợp kết quả trường hợp tương ứng với thuật toán

Như trên luận văn đã nêu một số thuật toán để phân tích con trỏ Cách giải quyết chung của 2 thuật toán là dựa trên lý thuyết giàn để tạo ra một phương trình ràng buộc, sau đó áp dụng thuật toán điểm cố định giải và thu được tập đích của con trỏ Tuy nhiên ta có thể phân tích con trỏ một cách tối ưu hơn bằng

cách phân tích hình dạng bộ nhớ heap Tức là nó có thể xác định tập point – to

chính xác hơn các kỹ thuật trên

3.2 Phân tích con trỏ liên thủ tục

Nếu hàm con trỏ được tham chiếu từ các con trỏ khác, thì ta có thể thực hiện

phân tích points – to liên thủ tục bằng cách đầu tiên tính toán liên thủ tục CFG

và sau đó chạy một trong hai thuật toán Andersen hoặc Steengaard Tuy nhiên,

nếu hàm con trỏ có tham chiếu gián tiếp thì khi đó ta cần thực hiện phân tích

Ngày đăng: 04/11/2015, 18:08

HÌNH ẢNH LIÊN QUAN

Hình 2.1.  Biểu đồ Hasse biểu diễn giàn - Kỹ thuật phân tích chương trình tĩnh cho bài toán phân tích hình dạng bộ nhớ heap
Hình 2.1. Biểu đồ Hasse biểu diễn giàn (Trang 15)
Hình 2.2.  Quan hệ thứ tự từng phần là giàn - Kỹ thuật phân tích chương trình tĩnh cho bài toán phân tích hình dạng bộ nhớ heap
Hình 2.2. Quan hệ thứ tự từng phần là giàn (Trang 16)
Hình 2.4.  Ví dụ giàn có chiều cao là 4  2.1.2. Thuộc tính đóng - Kỹ thuật phân tích chương trình tĩnh cho bài toán phân tích hình dạng bộ nhớ heap
Hình 2.4. Ví dụ giàn có chiều cao là 4 2.1.2. Thuộc tính đóng (Trang 17)
Hình 2.5.  Phép toán cộng giàn - Kỹ thuật phân tích chương trình tĩnh cho bài toán phân tích hình dạng bộ nhớ heap
Hình 2.5. Phép toán cộng giàn (Trang 18)
Hình 2.7.   Phép toán lift của các tập tạo thành giàn. - Kỹ thuật phân tích chương trình tĩnh cho bài toán phân tích hình dạng bộ nhớ heap
Hình 2.7. Phép toán lift của các tập tạo thành giàn (Trang 18)
Hình 2.6.   Phép toán nâng (lift) giàn. - Kỹ thuật phân tích chương trình tĩnh cho bài toán phân tích hình dạng bộ nhớ heap
Hình 2.6. Phép toán nâng (lift) giàn (Trang 18)
Hình 2.8.   Tính toán điểm cố định trên giàn - Kỹ thuật phân tích chương trình tĩnh cho bài toán phân tích hình dạng bộ nhớ heap
Hình 2.8. Tính toán điểm cố định trên giàn (Trang 21)
Hình 2.9.   Giàn có chiều cao vô hạn - Kỹ thuật phân tích chương trình tĩnh cho bài toán phân tích hình dạng bộ nhớ heap
Hình 2.9. Giàn có chiều cao vô hạn (Trang 23)
Hình 3.2.   Đồ thị heap - Kỹ thuật phân tích chương trình tĩnh cho bài toán phân tích hình dạng bộ nhớ heap
Hình 3.2. Đồ thị heap (Trang 34)
Hình 3.3.  Đồ thị hình dạng heap sau vòng lặp - Kỹ thuật phân tích chương trình tĩnh cho bài toán phân tích hình dạng bộ nhớ heap
Hình 3.3. Đồ thị hình dạng heap sau vòng lặp (Trang 36)
Hình 4.1.   Kết quả ví dụ rò rỉ bộ nhớ trong Memcheck - Kỹ thuật phân tích chương trình tĩnh cho bài toán phân tích hình dạng bộ nhớ heap
Hình 4.1. Kết quả ví dụ rò rỉ bộ nhớ trong Memcheck (Trang 44)
Hình 4.2.   Kết quả ví dụ sử dụng bộ nhớ chưa được khởi tạo trong Memcheck - Kỹ thuật phân tích chương trình tĩnh cho bài toán phân tích hình dạng bộ nhớ heap
Hình 4.2. Kết quả ví dụ sử dụng bộ nhớ chưa được khởi tạo trong Memcheck (Trang 46)
Hình 4.3.  Kết quả ví dụ sử dụng bộ nhớ chưa được khởi tạo trong Memcheck - Kỹ thuật phân tích chương trình tĩnh cho bài toán phân tích hình dạng bộ nhớ heap
Hình 4.3. Kết quả ví dụ sử dụng bộ nhớ chưa được khởi tạo trong Memcheck (Trang 47)
Hình 4.4.  Kết quả ví dụ lỗi sử dụng không đúng giữa malloc/new/new[] với - Kỹ thuật phân tích chương trình tĩnh cho bài toán phân tích hình dạng bộ nhớ heap
Hình 4.4. Kết quả ví dụ lỗi sử dụng không đúng giữa malloc/new/new[] với (Trang 48)
Hình trên cho ta thấy lỗi sử dụng khối bộ nhớ đã giải phóng và lỗi giải phóng 2  lần một khối bộ nhớ - Kỹ thuật phân tích chương trình tĩnh cho bài toán phân tích hình dạng bộ nhớ heap
Hình tr ên cho ta thấy lỗi sử dụng khối bộ nhớ đã giải phóng và lỗi giải phóng 2 lần một khối bộ nhớ (Trang 50)

TỪ KHÓA LIÊN QUAN

TRÍCH ĐOẠN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w