CHƯƠNG 4 các kỹ THUẬT KIỂM TRA TINH ĐÚNG đắn và TÍNH AN TOÀN của CHƯƠNG TRÌNH PHẦN mềm

128 907 0
CHƯƠNG 4 các kỹ THUẬT KIỂM TRA TINH ĐÚNG đắn và TÍNH AN TOÀN của CHƯƠNG TRÌNH PHẦN mềm

Đ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

• Với toán, làm để: – Thiết kế giải thuật nhằm giải toán – Cài đặt giải thuật chương trình máy tính - Hãy làm cho chương trình chạy trước tăng tính hiệu chương trình - Hãy tăng tính hiệu chương trình đồng thời thể tốt phong cách lập trình cá nhân CHƯƠNG IV CÁC KỸ THUẬT KIỂM TRA TÍNH ĐÚNG ĐẮN VÀ TÍNH AN TOÀN CỦA CHƯƠNG TRÌNH PHẦN MỀM I II III IV Bẫy lỗi (error handling) Lập trình phòng ngừa (defensive programming) Kiểm thử (Testing) Gỡ rối (Debugging) Mở đầu • Lỗi: chương trình chạy không định • Chuỗi kiểm tra chương trình – – – – Bẫy lỗi (error handling) Lập trình phòng ngừa (defensive programming) Kiểm thử (testing) Gỡ rối (debugging) • Phân biệt: – Bẫy lỗi: Prevent errors – Lập trình phòng ngừa: Detect problems as early as possible – Kiểm thử: finished code – Gỡ rối: fixing defects uncovered by testing I BẪY LỖI Nguyên tắc • Khi lỗi xảy cần – Định vị nguồn gây lỗi – Kiểm soát lỗi • Luôn có ý thức đề phòng lỗi hay xảy chương trình, đọc file, liệu người dùng nhập vào cấp phát nhớ • Áp dụng biện pháp phòng ngừa điều dẫn tới việc dừng chương trình • In lỗi stderr stream fprintf (stderr,"There is an error!\n"); Kiểm tra để phát lỗi ? • Kiểm tra thao tác gây lỗi viết CT – Nhập liệu – Sử dụng liệu • Ví dụ: – Kiểm tra lần mở tệp tin hay cấp phát ô nhớ – Kiểm tra phương thức người dùng nhập liệu vào không nguy gây dừng chương trình – Trong trường hợp tràn nhớ (out of memory), nên in lỗi kết thúc chương trình (-1: error exit); – Trong trường hợp liệu người dùng đưa vào bị lỗi, tạo hội cho người dùng nhập lại liệu (lỗi tên file người dùng nhập sai) Làm phát lỗi ? • Cần có cách xử lý lỗi mà ta chờ đợi xảy • Tùy theo tình cụ thể, ta – – – – – – – – – Trả 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ý Hiện thông báo lỗi Tắt máy Một số lỗi nhập liệu phổ biến • Dữ liệu nhập vào lớn (ví dụ, vượt kích thước kích thước lưu trữ cho phép mảng hay biến) • Dữ liệu nhập vào sai kiểu, giá trị nhỏ giá trị âm • Lỗi chia cho số (divide by zero) 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” – Thoá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 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; } Assertions • Assertions dùng để kiểm tra giả thiết : – Các tham số đầu vào nằm phạm vi mong đợi (tương tự với tham số đầu ra) – File hay stream mở (hay đóng) CTC bắt đầu thực (hay kết thúc) – file hay stream ghi (hay cuối cùng) CTC bắt đầu ( hay kết thúc) thực – file hay stream mở để đọc, để ghi, hay đọc ghi – Giá trị tham số đầu vào không thay đổi CTC – pointer non-NULL – mảng đc truyền vào CTC chứa X phần tử – bảng đc khởi tạo để chứa giá trị thực – danh sách rỗng (hay đầy) lkhi CTC bắt đầu (hay kết thúc) thực Assertions • • • • • End users không cần thấy thông báo assertion ; Assertions chủ yếu đc dùng trình phát triển hay bảo dưỡng ứng dụng Dịch thành code phát triển, loại bỏ khỏi code sản phẩm để nâng cao hiệu chương trình Rất nhiều NNLT hỗ trợ assertions : C++, Java Visual Basic Kể NNLT không hỗ trợ, dễ dàng xây dựng VD: #define ASSERT(condition, message) { if ( !(condition) ) { fprintf( stderr, "Assertion %s failed: %s\n", condition, message); exit( EXIT_FAILURE ); } } Dùng assertions ? • Bẫy lỗi cho tình lường trước (sự kiện ta chờ đợi xảy ra); – Error-handling : checks for bad input data  Hướng tới việc xử lý lỗi • Dùng assertions cho tình không lường trước (sự kiện không mong đợi xảy không xảy ra) – Assertions : check for bugs in the code  hướng đến việc hiệu chỉnh chương trình, tạo phiên chương trình • Tránh đưa code xử lý vào assertions – Điều xảy ta turn off the assertions ? Dùng assertions ? • Các chương trình lớn: – trước tiên xác nhận lỗi (dùng assertion), – sau bẫy lỗi (dùng error-handling) • Nguyên nhân gây lỗi xác định: – dùng assertion, dùng error-handling, – không dùng lúc • Các chương trình cực lớn, nhiều người phát triển thời gian 5-10 năm, ? – Cả assertions error handling code đc dùng cho lỗi – Ví dụ source code cho Microsoft Word, điều kiện trả true đc dùng assertion, đồng thời đc xử lý – Assertions có lợi giúp loại bỏ nhiều lỗi trình phát triển hệ thống Kiểm tra giá trị không thay đổi • Có thể sử dụng assert để kiểm tra giá trị không thay đổi #ifndef NDEBUG int isValid(MyType object) { … Test invariants here Return (TRUE) if object passes all tests, and (FALSE) otherwise … } #endif void myFunction(MyType object) { assert(isValid(object)); … Manipulate object here … assert(isValid(object)); } 2.6 Hiện thị kết đầu • In giá trị biến điểm có khả gây lỗi để định vị khu vực gây lỗi, • Xác định tiến trình thực : “đến 1” • Poor: printf("%d", keyvariable); • Maybe better: stdout is buffered; CT có lỗi trước output In '\n' xóa nhớ đệm stdout , không xóa in file printf("%d\n", keyvariable); • Better: printf("%d", keyvariable); fflush(stdout); Gọi fflush() để làm buffer cách tường minh Hiện thị kết đầu • Tạo log file • Lưu vết – Giúp ghi nhớ đc vấn đề xảy ra, giải vđề tương tự sau này, chuyển giao CT cho người khác • Maybe even better: fprintf(stderr, "%d", keyvariable); • Maybe better still: FILE *fp = fopen("logfile", "w"); … fprintf(fp, "%d", keyvariable); fflush(fp); In debugging output stderr; debugging output tách biệt với đầu thông thường cách in ấn CT Ngoài ra: stderr không dùng buffer Ghi a log file 2.7 Sử dụng trình gỡ rối (debugger) • • • • • • • IDE : kết hợp soạn thảo, biên dịch, gỡ rối … Các trình gỡ rối với giao diện đồ họa cho phép chạy chương trình bước qua lệnh hàm, dừng dòng lệnh đặc biệt hay xuất đk đặc biệt, bên canh có công cụ cho phép định dạng hiển thị giá trị biến, biểu thức Trình gỡ rối kích hoạt trực tiếp có lỗi gắn vào chương trình chạy Thường để tìm lỗi , ta phải xem xét thứ tự hàm đc kích hoạt ( theo vết) hiển thị giá trị biến liên quan Nếu không phát đc lỗi : dùng BreakPoint hoạc chạy bước – step by step Có nhiều công cụ gỡ rối mạnh hiệu quả, ta nhiều thời gian trí lực để gỡ rối ? Nhiều công cụ giúp dễ dàng tìm lỗi, đưa câu hỏi sai, trình gỡ rối cho câu trả lời, ta bị sai Sử dụng trình gỡ rối • • ( • • • Dùng trình gỡ rối để chạy bước phương sách cuối Nhiều vấn đề tưởng đơn giản lại không phát được, ví dụ toán tử so sánh pascal va VB có độ ưu tiên ngang nhau, với C ? == != nhỏ !) Thứ tự đối số lời gọi hàm : ví dụ : strcpy(s1,s2) int m[6]={1,2,3,4,5,6}, *p,*q; p=m; q=p+2; *p++ =*q++; *p=*q; ??? Lỗi loại khó tìm thân ý nghĩ ta vạch hướng suy nghĩ sai lệch : coi điều không Đôi lỗi nguyên nhân khách quan : Trình biên dịch, thư viện hay hệ điều hành, lỗi phần cứng : 1994 lỗi xử lý dấu chấm độngng xử lý Pentium Công cụ hỗ trợ gỡ rối GDB: The GNU Project Debugger • Gỡ rối chương trình viết Ada, C, C++, Objective-C, Pascal, v.v., chạy máy cài đặt GDB hay máy khác • Hoạt động UNIX Microsoft Windows • Các chức hỗ trợ: – Bắt đầu chương trình, xác định yếu tố làm ảnh hưởng đến hoạt động chương trình – Dừng chương trình với điều kiện biết trước – Khi chương trình bị dừng, kiểm tra xảy – Thay đổi lệnh chương trình để LTV thử nghiệm gỡ rối lỗi 2.8 Tập trung vào lệnh viết / viết lại • Kiểm tra thay đổi – Lỗi thường xảy đoạn CT bổ sung – Nếu phiên cũ OK, phiên có lỗi => lỗi chắn nằm đoạn CT – Lưu ý, sửa đổi, nâng cấp : giữ lại phiên cũ – đơn giản comment lại đoạn mã cũ – Đặc biệt, với hệ thống lớn, làm việc nhóm việc sử dụng hệ thống quản lý phiên mã nguồn chế lưu lại trình sửa đổi vô hữu ích ( source safe ) Tập trung vào lệnh viết / viết lại • Các lỗi xuất thất thường : – Khó giải – Thường gán cho lỗi máy tính, hệ điều hành … – Thực thông tin CT : thuật toán, mà thông tin bị thay đổi qua lần chạy – Các biến đc khởi tạo hết chưa ? – Lỗi cấp phát nhớ ? Vd : char *vd( char *s) { char m[101]; strncpy(m,s,100) return m; } – Giải phóng nhớ động ? – for (p=listp; p!=NULL; p=p->next) free(p) ; ??? Tập trung vào lệnh viết / viết lại • Phải gỡ rối ngay, không nên để sau – Khó: Viết toàn chương trình; kiểm tra toàn chương trình, gỡ rối toàn chương trình – Dễ hơn: Viết đoạn, kiểm tra đoạn, gỡ rối đoạn; viết đoạn, kiểm tra đoạn, gỡ rối đoạn; • Nên giữ lại phiên trước – Khó: Thay đổi mã nguồn, đánh dấu lỗi; cố gắng nhớ xem thay đổi từ lần làm việc trước – Dễ hơn: Backup mã nguồn, thay đổi mã nguồn, đánh dấu lỗi; so sánh phiên với phiên cũ để xác định điểm thay đổi Giữ lại phiên trước • Cách 1: Sao chép tay vào thư mục … $ mkdir myproject $ cd myproject Create project files here $ cd $ cp –r myproject myprojectDateTime $ cd myproject Continue creating project files here … • Lặp lại lần có phiên • Cách 2: dùng công cụ RCS (Revision Control System), CVS, v.v Tóm lại • Gỡ rối nghệ thuật mà ta phải luyện tập thường xuyên • Nhưng nghệ thuật mà ta không muốn • Mã nguồn viết tốt có lỗi dễ tìm • Đầu tiên phải nghĩ đến nguồn gốc sinh lỗi • Hãy suy nghĩ kỹ càng, có hệ thống để định vị khu vực gây lỗi • Không học từ lỗi – điều LTV [...]... khi gọi mỗi phần chương trình: điều gì phải đúng trước khi gọi chương trình, điều gì xảy ra sau khi chương trình thực hiện xong – Dùng chú thích để miêu tả cấu trúc chương trình khi viết chương trình Kiểm tra cái gì, khi nào ? • Testing: chỉ ra các vấn đề làm chương trình không chạy • Kiểm tra theo cấu trúc của chương trình: Kiểm tra việc thực hiện các nhiệm vụ đặt ra cho từng phần chương trình – Ví... thành chương trình trước ít nhất 3 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 khi viết bằng ngôn ngữ lập trình cụ thể • Giữ vững cấu trúc chương trình: – Viết và kiểm thử từng phần chương trình: phần chương trình nào dùng để làm gì – Viết và kiểm thử mối liên kết giữa các phần trong chương trình: quy trình nghiệp vụ như thế nào – Phòng ngừa bằng các điều kiện trước và sau... Lỗi liên quan đến người dùng – Đừng cho rằng người dùng luôn thực hiện đúng các thao tác theo chỉ dẫn, hãy kiểm tra mọi thao tác của họ • Lỗi liên quan đến các kỹ thuật phòng ngừa! – Mã nguồn cài đặt các kỹ thuật phòng ngừa cũng có khả năng gây lỗi, kiểm tra kỹ phần này 3 Các giai đoạn lập trình phòng ngừa • Lập kế hoạch thực hiện công việc: – Dành thời gian để kiểm tra và gỡ rối chương trình cẩn thận... như thế nào ? Bộ nhớ máy tính Mảng có khả năng bị tràn Code khác Chương trình đang chạy Ghi vào mảng (gửi dữ liệu có chứa chương trình gây hại vào CT đang chạy ) Lots of "no operations" Chương trình gây hại Chương trình đang chạy thử tiếp tục chạy trên phần bộ nhớ dành cho nó, nhưng mà phần bộ nhớ này đã bị chương trình gây hại chiếm mất khi thực hiện phép ghi vào mảng II LẬP TRÌNH PHÒNG NGỪA 1 Khái... với chương trình căn lề văn bản, nếu hàm ReadWord() bị lỗi ? • Nếu chương trình không có tham số đầu vào, mà chỉ thực thi nhiệm vụ và sinh ra kết quả thì không cần kiểm tra nhiều Hầu hết chương trình đều không như vậy – Ví dụ: điều gì xảy ra với chương trình căn lề văn bản, nếu • Không nhập đầu vào ? • Đầu vào không phải là xâu/file chứa các từ hay chữ cái đúng quy định ? a Kiểm tra tham số đầu vào... có thể biết chương trình có chạy thông hay không khi kiểm tra chương trình bằng các tham số đầu vào sai Tham số đầu vào sai • Trong thực tiễn: “Garbage in, garbage out.” – GIGO • Trong lập trình, “rác vào – rác ra” là dấu hiệu của những CT tồi, không an toàn • Với 1 CT tốt thì: – “rác vào, không có gì ra”, – “rác vào, có thông báo lỗi” – “không cho phép rác vào” Phòng ngừa lỗi tham số vào • Check... số đầu vào • Một phần chương trình chạy thông 1 lần không có nghĩa là lần tiếp theo nó sẽ chạy thông • Chương trình trả ra kết quả đúng với đầu vào 'n' không có nghĩa là nó sẽ trả ra kết quả đúng với đầu vào ‘m’ ‘n’ • Vậy chương trình có thực sự chạy thông không ? – Với bất cứ đầu vào nào chương trình cũng phải chạy thông, không bị “crash” Nếu có lỗi thì chương trình phải dừng và thông báo lỗi –... hưởng tiêu cực của dữ liệu không hợp lệ – các rủi ro đến từ các sự kiện tưởng như "không bao giờ" xảy ra – sai lầm của các lập trình viên khác 2 Các lỗi có thể phòng ngừa • Lỗi liên quan đến phần cứng – Đảm bảo các lỗi như buffer overflows hay divide by zero được kiểm soát • Lỗi liên quan đến chương trình – Đảm bảo giá trị gán cho các biến luôn nằm trong vùng kiểm soát – Do not trust anything; verify... thác các lỗi (bug) của hệ điều hành (Windows/Unix/Mac OS) hay phần mềm để truy nhập trái phép vào máy tính • Một trong những lỗi được khai thác rất nhiều là "buffer overflows" • Có nhiều cách gây ra buffer overflows – Sử dụng cẩu thả "strcpy" (sao chép 1 xâu lớn hơn vào 1 biến có kích thước nhỏ hơn) – Dùng lệnh gets (thư viện stdio) – Quên không kiểm tra độ lớn của xâu vào – • Kiểm tra dữ liệu vào từ... all routine input parameters – Kiểm tra giá trị của tất cả các tham số truyền vào các hàm cùng cần như kiểm tra dữ liệu nhập từ nguồn ngoài khác • Decide how to handle bad inputs – Khi phát hiện 1 tham số hay 1 dữ liệu không hợp lệ, bạn cần làm gì với nó? Tùy thuộc tình huống, bạn có thể chọn 1 trong các phương án phù hợp Phòng ngừa lỗi tham số vào • Kiểm tra giá trị của mọi dữ liệu từ nguồn bên ngoài ...CHƯƠNG IV CÁC KỸ THUẬT KIỂM TRA TÍNH ĐÚNG ĐẮN VÀ TÍNH AN TOÀN CỦA CHƯƠNG TRÌNH PHẦN MỀM I II III IV Bẫy lỗi (error handling) Lập trình phòng ngừa (defensive programming) Kiểm thử (Testing)... cấu trúc chương trình viết chương trình Kiểm tra gì, ? • 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. .. 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ử

Ngày đăng: 11/11/2015, 16:48

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan