Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 51 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Tiêu đề
Bẫy Lỗi Và Lập Trình Phòng Ngừa
Định dạng
Số trang
51
Dung lượng
6,25 MB
Nội dung
Chương 8: Bẫy lỗi lập trình phịng ngừa Nội dung Khái niệm Bảo vệ chương trình liệu đầu vào không hợp lệ (Invalid Inputs) Assertions Kỹ thuật xử lý lỗi Xử lý ngoại lệ Nội dung Khái niệm Bảo vệ chương trình liệu đầu vào khơng hợp lệ (Invalid Inputs) Assertions Kỹ thuật xử lý lỗi Xử lý ngoại lệ Lập trình phịng ngừa Defensive Programming vs Defensive driving Khái niệm Lập trình phịng ngừa - Defensive programming • Lập trình phịng ngừa cách tự bảo vệ chương trình khỏi • ảnh hưởng tiêu cực liệu khơng hợp lệ • rủi ro đến từ kiện tưởng "khơng bao giờ" xảy • sai lầm lập trình viên khác • Ý tưởng chính: chương trình (CTC) nhận liệu vào bị lỗi chạy thơng, chương trình khác nhận liệu đầu vào bị lỗi Các lỗi phịng ngừa • Lỗi liên quan đến phần cứng • Đảm bảo lỗi buffer overflows hay divide by zero kiểm sốt • Lỗi liên quan đến chương trình • Đảm bảo giá trị gán cho biến nằm vùng kiểm sốt • Do not trust anything; verify everything • Lỗi liên quan đến người dùng • Đừng cho người dùng thực thao tác theo dẫn, kiểm tra thao tác họ • Lỗi liên quan đến kỹ thuật phịng ngừa! • Mã nguồn cài đặt kỹ thuật phịng ngừa có khả gây lỗi, kiểm tra kỹ phần Các giai đoạn lập trình phịng ngừa • Lập kế hoạch thực cơng việc: • Dành thời gian để kiểm tra gỡ rối chương trình cẩn thận : hồn thành chương trình trước ngày so với hạn nộp • Thiết kế chương trình: • Thiết kế giải thuật trước viết ngơn ngữ lập trình cụ thể • Giữ vững cấu trúc chương trình: • Viết kiểm thử phần chương trình: phần chương trình dùng để làm • Viết kiểm thử mối liên kết phần chương trình: quy trình nghiệp vụ • Phịng ngừa điều kiện trước sau gọi phần chương trình: điều phải trước gọi chương trình, điều xảy sau chương trình thực xong • Dùng thích để miêu tả cấu trúc chương trình viết chương trình Kiểm tra gì, nào? • Testing: vấn đề làm chương trình khơng chạy • Kiểm tra theo cấu trúc chương trình: Kiểm tra việc thực nhiệm vụ đặt cho phần chương trình • Ví dụ: điều xảy với chương trình lề văn bản, hàm ReadWord() bị lỗi ? • Nếu chương trình khơng có tham số đầu vào, mà thực thi nhiệm vụ sinh kết khơng cần kiểm tra nhiều Hầu hết chương trình khơng • Ví dụ: điều xảy với chương trình lề văn bản, • Khơng nhập đầu vào? • Đầu vào khơng phải xâu/file chứa từ hay chữ quy định? Kiểm soát lỗi xảy • Error handling: xử lý lỗi mà ta dự kiến xảy • Tùy theo tình cụ thể, ta trả về: • giá trị trung lập • thay đoạn liệu hợp lệ • trả giá trị lần trước • thay giá trị hợp lệ gần • ghi vết cảnh báo vào tệp • trả mã lỗi • gọi thủ tục hay đối tượng xử lý • thông báo hay tắt máy Nội dung Khái niệm Bảo vệ chương trình liệu đầu vào không hợp lệ (Invalid Inputs) Assertions Kỹ thuật xử lý lỗi Xử lý ngoại lệ 10 Phục hồi tài nguyên • Phục hồi tài ngun xảy lỗi? • Thường khơng phục hồi tài nguyên, hữu ích thực công việc nhằm đảm bảo cho thông tin trạng thái rõ ràng vơ hại • Nếu biến cịn truy xuất chúng nên gán giá trị hợp lý • Trường hợp thực thi việc cập nhật liệu, phiên – transaction – liên quan tới nhiều bảng chính, phụ, việc khơi phục có ngoại lệ vơ cần thiết (rollback ) 37 Chắc chắn hay xác? • Chắc chắn: chương trình ln chạy thơng, kể có lỗi • Chính xác: chương trình khơng gặp lại lỗi • Ví dụ: Lỗi thị trình xử lý văn bản: thay đổi nội dung văn bản, phần dòng văn phía hình bị thị sai Khi người dùng phải làm gì? • Tắt chương trình • Nhấn PgUp PgDn, hình làm Ưu tiên tính chắn thay tính xác: • Bất kết thường tốt so với Shutdown 38 Khi phải loại bỏ hết lỗi? • Đơi khi, để loại bỏ lỗi nhỏ, lại tốn • Nếu lỗi chắn khơng ảnh hưởng đến mục đích ứng dụng, khơng làm chương trình bị treo, làm sai lệch kết chính, người ta bỏ qua, mà khơng cố sửa để gặp phải nguy khác • Phần mềm “chịu lỗi”?: Phần mềm sống chung với lỗi, để đảm bảo tính liên tục, ổn định 39 Dùng hàm bao gói (Wrappered function) • Hàm bao gói = gọi hàm gốc + bẫy lỗi • Tại thời điểm cần kiểm tra lỗi hàm gốc, dùng hàm bao gói thay dùng hàm gốc • Ví dụ: • Nếu phải viết đoạn mã kiểm tra lỗi lần sử dụng malloc nhàm chán • Kiểm tra • Thơng báo lỗi kiểu “out of memory” • Thốt • Tự viết hàm safe_malloc sử dụng hàm thay dùng malloc có sẵn • Malloc • Kiểm tra • Thơng báo lỗi kiểu “out of memory” • Thoát 40 safe_malloc #include #include void *safe_malloc (size_t); /* Bẫy lỗi dùng hàm malloc */ void *safe_malloc (size_t size) /* Cấp phát nhớ báo lỗi thoát */ { void *ptr; ptr= malloc(size); if (ptr == NULL) { fprintf (stderr, “Không đủ nhớ để thực dòng lệnh :%d file :%s\n", LINE , FILE ); exit(-1); } return ptr; } 41 Tạo giao diện rõ ràng • Các LTV giỏi ln tìm cách làm cho mã nguồn họ trở nên hữu dụng với LTV khác • Cách tốt để làm việc viết hàm dễ hiểu, có khả tái sử dụng • Các hàm tốt không cần đến nhiều tham số truyền vào • Để viết tốt hàm, cần tư theo hướng: • Cần truyền vào để thực hàm? • Có thể lấy sau thực hàm • Nếu LTV có khả viết giao diện rõ ràng hàm tự thân trở nên hiệu quả: • Các hàm cung cấp • Cách thức truy nhập chức muốn cung cấp 42 Nội dung Khái niệm Bảo vệ chương trình liệu đầu vào không hợp lệ (Invalid Inputs) Assertions Kỹ thuật xử lý lỗi Xử lý ngoại lệ 43 Xử lý ngoại lệ • Xử lý exception thực thơng qua keywords: try, catch, throw • Các đoạn code có khả gây lỗi cần phải đặt khối lệnh try Khối try không thay đổi việc thực thi phần code bên Nó kích hoạt chức quan sát theo dõi exception • Một exception phát sinh “một exception bị throw (ném ra)” • Khi exception ném ra, việc thực thi block code chấm dứt, thân chương trình cịn sống Nếu khơng có đoạn code xử lý bắt exception (khối catch), chương trình kết thúc 44 Xử lý ngoại lệ • try − đặt phần code xảy exception khối try • throw − Khi có bất thường xảy chương trình, sử dụng keyword throw để ném ngoại lệ • catch − Nếu muốn bắt exception nào, cần phải đặt câu lệnh catch sau câu lệnh try Lệnh catch sẽ try { //exception protected code bắt tương thích với kiểu } catch( ExceptionType e1 ) { định // catch block } catch( ExceptionType e2 ) { // catch block } catch( ExceptionType eN ) { // catch block } 45 Ném ngoại lệ • Để “ném” exception, sử dụng câu lệnh throw Câu lệnh throw cần cung cấp liệu “đóng gói” exception throw 997; throw string("Bye world!"); double division(int a, int b) { if( b == ) throw "Division by zero!"; } return (a/b); } 46 Bắt ngoại lệ • Đặt khối lệnh catch sau khối lệnh try để bắt ngoại lệ Lệnh catch sẽ bắt exception tương thích với kiểu định try { // protected code } catch( ExceptionType e ) { // code to handle ExceptionType exception } • Đoạn code bắt ngoại lệ có kiểu là ExceptionType Nếu muốn lệnh catch bắt exception thuộc try { kiểu liệu nào, sử dụng dấu “…” // protected code } catch( ) { // code to handle any exception } 47 Ví dụ #include using namespace std; double division(int a, int b) { if( b == ) { throw "Division by zero!"; } return (a/b); } int main () { int x = 50; int y = 0; double z = 0; try { z = division(x, y); cout