程式除錯技術 (Debugging Techniques)

Download Report

Transcript 程式除錯技術 (Debugging Techniques)

國立中央大學 資訊工程系 鄭永斌 教授
教育部資訊人才培育計畫
1
 兩種技術常常被混為一談
 軟體測試(software testing) 是
 透過各種測試的技術與工具發現BUG
 通常由QA (Tester)人員負責
 使用測試輔助工具
 軟體除錯(debugging)
 BUG 發現之後,找出問題的源頭,修正程式的行為,
使錯誤能在未來的測試的過程中不再出現
 由程式開發人員負責
 使用除錯工具
教育部資訊人才培育計畫
2
產
品
缺
陷
率
software development
其他工程製造
QC 改進時程
4
有天晚上我參加一個老同學的喜宴,
同桌的人有律師、會計師,
只有我一個是電腦業界的人。
為了引起話題,我說我羨慕其他行業的
人,像是律師、會計師等,在學校學
的那一套終生都受用,每年就算有新
法條也不會改太多。
不像我們電腦界的人,每天都在K新的技
術手冊,新產品新技術隨時大翻新,
改朝換代的速度讓人措手不及,所以
學電腦的人看起來都比較蒼老,因為
太辛苦了。
頓時我成了眾矢之的,
這些電腦使用者的抱怨全部集中到我身上
來。
其中一位仁兄還舉了個有趣的例子,
他說:
「如果傢俱業和電腦業一樣,世界會變成
什麼樣子?」以下是他講的故事:
如果傢俱業跟電腦業一樣,比如說我到傢
我話剛說完,一位會計師馬上回我一句:
俱店買了一張桌子,搬回家往地板上一放,
「你錯了,其實我們最羨慕你們電腦
啪啦一聲桌子就塌了。這時候我不會生氣、
界的人,因為沒有任何行業的消費者
像你們電腦界的消費者一樣好欺負。」 不會罵人,我會先自己檢查一下出了什麼
錯。
5
我會先檢討自己,
是不是我做錯了什麼,
或是我對桌子的使用不夠熟悉。
於是我會去買書來看
(書名可能是《快快樂樂學修桌子》、
《21天學會修桌子》、《修桌子技巧與
實例》、
或是《修桌子的聖經》)。
要是書看得不太懂,
我會再花錢去報名上修桌子的課程。
學完之後還是修不好,
我會請其他比較懂得修桌子的朋友來幫
忙。
最後沒有辦法,
終於我打電話給原先的傢俱行,
(可能還要購買《技術支援方案》),
結果他們跟我說:
「唉呀!你買到的是搶鮮版啦!
本來就應該有問題的」。
於是我恍然大悟原來是自己的錯,
我就再去買一張「正式版」的桌子。
回家一擺還是啪啦又塌了!
修了半天還是有問題,
再請傢俱行的技術人員來做仔細檢查,
最後終於發現問題的所在──
「我家的地板和桌子不相容」,
又是我自己的錯,
於是我得趕快幫家裡的地板升級......。
等一切都忙完了,
桌子可以使用了,
我趴在桌上寫字,
心裡充滿了成就感,
我很得意地跟網友分享我修理桌子的經驗,
並暗自慶幸自己在科技的潮流上沒有落
伍......。
6
 如同前面所說的,由於軟體產業的生產工
具是人,人注定會犯錯。如果還是很多人
一起合作,還會犯更多的錯!
 No humans (programmers) are perfect
 如果你想要建造真的能給人使用的軟體 –
軟體測試,在實務界非常重要
7
A software bug (臭蟲) is the common term
used to describe an error, flaw, mistake, failure,
or fault in a computer program or system that
produces an incorrect or unexpected result, or
causes it to behave in unintended ways.
教育部資訊人才培育計畫
8
1946 Grace MurrayHopper (電腦科學的女性先驅, 發明 COBOL 語言)
於Mark III 的真空管電腦發現一隻飛蛾導致軟體錯誤所寫下的手稿 珍藏於National
Museum of American History
教育部資訊人才培育計畫
9
 程式碼中的人為錯誤 (例如: 打字的錯誤)
 設計與邏輯的錯誤
 編譯器造成的錯誤 (遠遠較為稀少)
 記憶體管理錯誤
 規格錯誤
 第三方軟體 (程式庫)的錯誤
教育部資訊人才培育計畫
10
Logical Bugs
由於系統設計不週詳,資料結構設
計不良,邏輯思考不夠周延所導致
的臭蟲。
通常修復的代價很高
可能需要翻修許多程式或資料結構
Wiring Bug
線路錯亂導致的臭蟲。
通常是因為程式碼的可能執
行路徑太多,未經過深思以
比較好的程式技巧或演算法
來解決問題。
修正此一類的錯誤需要費一
點力氣,但是不需要大幅整
修既有的程式碼,但是通常
會越修越雜亂
引用自
Rendering Bug
一旦發現錯誤, 錯誤的原因很明
顯,白目或無喱頭,例如少了
一個分號,或== 寫成 =
 probability to find the bugs –
Low:你可能執行了許多測試案例才會出現,但
是不見得特別去設計測試案例來逼迫你的程式
碼執行到某部份的程式碼
 High:稍微執行一些測試案例就會發現

 difficulty to find the bugs –
Low: 不用太困難刁專的測試案例就可以發現
 High:需要特別設計的測試案例才能讓你的程式
行為能夠到達錯誤觸發的滿足條件

教育部資訊人才培育計畫
17
 現代的軟硬體不斷地精進,引入了許多新
的軟體技術。或因為時代的演進讓某些較
複雜的技術普及到一般的程式應用
多執行緒 Multithreading
 網路 Networking
 GUI 與物件導向系統 –

 將系統部分執行緒的行為封裝與遮蔽起來

Signal/CallBack (Interrupt-Driven Like
System)
 上述的技術引入了許多不尋常的 bug
教育部資訊人才培育計畫
18
 Heisengbug
 源自海森堡測不準原理 (Heisenberg Uncertainty
Principle)
 很難重現 bug
 雖然可以重現,但是一旦觀察之後就消失
 程式行為在 debug mode, optimization mode,
release mode 不一樣
 Examples
 race condition
 deadlock
 memory not properly cleaned and initiated.
教育部資訊人才培育計畫
19
 Bohrbug

特定條件成立才會發生的 bug,但是通常要讓
條件成立不容易,一般測試很難涵蓋到
 Examples

an overflow bug
教育部資訊人才培育計畫
20
 Schrödinbug (薛丁格臭蟲)
當某段程式碼被研讀了之後或以非常不正常的
方式使用之後才會展現
 通常是某位程式人員以非正規,不正常的方式
所撰寫的程式碼。這段程式碼只有在非常極端
的情況下才會被執行,但是一旦執行起來則立
即見光死

 註:
這位程式設計人員根本不應該被聘僱
 註: 你需要 code review 來防止
教育部資訊人才培育計畫
21
 Statistical bug


無法在單一一次執行重現的臭蟲
必須要在不斷累積的執行當中才能展現的臭蟲
 Example

程式牽涉到機率與亂數的運算
教育部資訊人才培育計畫
22
 這件事情在許多情境下,可能不是一件直
覺與簡單的事情, 尤其



bug 是屬於 unusual bugs
難以重現或重建臭蟲發生的執行環境
臭蟲發生於累積的資料,但是資料的內容無法
取得 (使用者須保密資料)
教育部資訊人才培育計畫
23
教育部資訊人才培育計畫
24
 軟體開發隨著系統複雜度與開發人員人數的增
加,需要一套方法來追蹤與記錄事情的進度與
解決狀況
 如果你是一個程式開發人員


也許你認為你可以把你要做的事情完整的記憶在與
管理在你的大腦中 – 但是經驗告訴你,你的自信
完全沒有道理
大腦是一個不可靠的器官
 如果你是一個專案管理經理
 你希望有個方法或系統隨時了解專案的狀況
 你希望有一套方法或系統不會讓你遺忘不明顯但是
卻重要的細節,並且確保有人在負責這些細節
教育部資訊人才培育計畫
25
 Call center
 help desk
 在這些服務導向的產業,如何做好服務,確保
每件事情都有負責人在處理是很重要的事情
教育部資訊人才培育計畫
26
 TICKET
當有一件任務或問題(ISSUE)要進行時,我們讓
系統產生一個描述此任務的 ticket
 一個 ticket 的主要屬性

 Unique
ID
 Issue 的重要性
 誰啟動了這個 ticket
 誰要負責處理這個 ticket
教育部資訊人才培育計畫
27
教育部資訊人才培育計畫
28
 一個 TICKET 轉
移流程範例
教育部資訊人才培育計畫
29
 http://trac.edgewall.org/
教育部資訊人才培育計畫
30
 An open source issue tracking system
 本課程要使用它來做為 bug tracking
system
 Please login to

http://140.115.155.110/trac/bugreport
 授課教師的帳號請參考本頁的講義
教育部資訊人才培育計畫
31
The Wiki pages
for your project
教育部資訊人才培育計畫
32
教育部資訊人才培育計畫
33
教育部資訊人才培育計畫
34
教育部資訊人才培育計畫
35
教育部資訊人才培育計畫
36
教育部資訊人才培育計畫
37
教育部資訊人才培育計畫
38
教育部資訊人才培育計畫
39
教育部資訊人才培育計畫
40


帳號:student01 - student29
密碼:student12345
 假設你執行了計算機進行運算出現了





bug。讓我們假設進行5+5的運算結果得
到11
利用螢幕擷取錯誤那一瞬間的影像(請
照做)
打開小畫家
框選你要的畫面
裁剪
存檔成 calc.jpg
教育部資訊人才培育計畫
41
Supposeyou know
the owner
教育部資訊人才培育計畫
42
教育部資訊人才培育計畫
43
教育部資訊人才培育計畫
44
教育部資訊人才培育計畫
45
教育部資訊人才培育計畫
46
 許多的程式執行時可能有
 輸入檔
 輸出檔
 Log files
 Core dump (memory dump)
 Error log files
 Tracing information (generated by Tracing
tools)
 ……
 在建立 bug 的當下,可以將這些檔案上傳到
ticket 中,方便程式開發人員更有效率地除
錯
教育部資訊人才培育計畫
47
教育部資訊人才培育計畫
48
 Trac 會送給你一個電子郵件, 如果你是該
ticket 的 OWNER
 如果你給 ticket 選擇了 component,表
示你知道這個錯誤的初步歸屬,則內定的
owner 會是該 component 的負責人
 此時 ticket 會處於 new 或是 assigned
的狀態直到有人 accept 為止
教育部資訊人才培育計畫
49
 New
 Assigned – 這個 ticket 理論上已經有
人初步處理過,也完成了工作指派, 但是
還沒有得到負責人的確認
 Accepted – 這個 ticket 已經有人確認
要進行處理 (任何人其實都可以去搶著確
認一個 ticket)
 Closed – 這個ticket 已經處理完成
 Reopened – 這個ticket 是一個被重新打
開的 ticket
教育部資訊人才培育計畫
50
 打開或重新submit 一些 tickets
 將ticket 指派給你的同學X
 請你的同學X 將 ticket 轉給同學Y
 請同學Y接受 ticket
 請你的同學 Y 再次打開 ticket
 設定該 ticket 為 fixed,並加入一些處
理時的comments
 請你將該 ticket 關掉設為 closed
教育部資訊人才培育計畫
51
教育部資訊人才培育計畫
52
 請利用帳號去建立一些 ticket
 將 TICKET 的狀態由 NEW 變成 ASSIGNED,
Accepted, 然後 closed
教育部資訊人才培育計畫
53
教育部資訊人才培育計畫
54
教育部資訊人才培育計畫
55
教育部資訊人才培育計畫
56
教育部資訊人才培育計畫
57
教育部資訊人才培育計畫
58
 Redmine http://www.redmine.org/
 BugZilla
http://www.bugzilla.org/
 Mantis www.mantisbt.org
教育部資訊人才培育計畫
59
 Bug history
analysis
(Bugzilla)
 Bug
report/history
本身可以視為一個
專案的健康指標。
從這些資料當中可
以做出各種種類的
分析
教育部資訊人才培育計畫
60
 人腦是一個非常不可靠的器官
請不要設想你可以將所有的事情記載你腦
中
 隨著程式開發的複雜度持續增加, 你可以
使用 Trac 來管理你自己的工作
增加 ticket types – future works,
incomplete tasks, ….
 隨時將未完成的工作建立成tickets

教育部資訊人才培育計畫
61
 Trac 也可以做為簡單的專案管理工具
 適合小團隊
 範例
 建立新的ticket 類別: feature 以及 tasks
 將系統規格所描述的 features 全部建立到
Trac ticket 中, 並且建立好 milestone, 以
及 components
 在一個 development iteration 中, 將
feature 變成 tasks
 在程式開發的進展中持續消化 feature 直到專
案完成
教育部資訊人才培育計畫
62
 如果你要產出一個 usable 的軟體,使用
bug tracking 系統是不可避免的
 Trac 可以與版本控制系統 subversion 一
起運作
 WIKI 的介面
教育部資訊人才培育計畫
63
教育部資訊人才培育計畫
64
 除錯(Debug),是程式開發的必然過程。據
研究,程式人員花在除錯上的時間約佔1/3
的工作時間。
 正規課程不太教授的內容
 教師認為學生程式寫多了就應該會自行學
會的技術(?)
 除錯的困難度與系統的複雜度成正比
 除錯的困難度會與使用的 programming
language 正相關 – e.g., 高階語言除錯
比較容易
教育部資訊人才培育計畫
65
1. 重現 bug (can be a non-trivial task in
many applications)
2. 視狀況簡化除錯案例與問題


例子1: 程式讀取很大的資料檔,在過程中發生錯
誤。若能找到經過簡化的資料檔還是可以造成一
樣的錯誤,除錯過程就可以比較輕鬆與有效率。
這個過程通常是由經驗累積的除錯智慧。
例子2: 程式進行了許多步驟造成錯誤,藉由skip
某些步驟,試看看情況是否一樣 (Divide and
Conquer)
3. 使用除錯器(或列印變數)一步一步找出問題
的源頭
教育部資訊人才培育計畫
66
 PRINT variables
會寫程式的人通常會使用的最基本的技巧
 在程式碼中插入 printf/cout 來列印關鍵位置
的重要變數內容
 一般列印到螢幕上或檔案
 除非插入等待的指令, 否則列印完畢不會停止
 讓程式碼在關鍵的地方產生log 也是屬於這類
的技巧

教育部資訊人才培育計畫
67
PRINT variable 在實務上會有下列的問題
 若要更改觀察的內容(譬如要多印幾個變數),需
要修改程式碼。但是修改程式碼須經過重新編譯
的過程,大系統的重新編譯過程可能非常久,因
為DEBUG而重新編譯整個系統,在一些實務中不僅
愚蠢而且沒有效率。
 列印變數的程式碼可以複雜到將資料排列輸出特
定的視覺化,不過一旦列印的程式碼變得複雜,
本身可能成為被除錯的對象
 列印到螢幕或檔案的選項在許多應用無法適用


GUI的應用
需要高效能的程式若加入PRINT 指令(尤其是輸出到螢幕
或檔案), 會讓程式執行變得非常緩慢,或製造更多的問
題
教育部資訊人才培育計畫
68
 請比較下面兩隻程式的執行時間
for (i=0;i<1000000; i++) {
value = i * i ;
}
for (i=0; i< 1000000; i++) {
value = i * i ;
cout << i << endl ;
}
 其執行速度可以差別非常非常大。不難發現
PRINT 指令對系統執行效能的干擾
教育部資訊人才培育計畫
69
 你為了瞭解程式的內部狀態,所以做了探
測 (加入 PRINT指令)
 因為你探測了,所以其實你也改變了系統
的行為,此效應稱之為 probe effect
 海森堡測不準原理
教育部資訊人才培育計畫
70
 若你待除錯的程式(debuggee)是只有一個
執行緒的sequential program
大部分只有影響效能但是沒有影響程式的對錯
(學校課程作業屬於此大宗),程式只是比較慢
走到你想要的地方
 錯誤通常能一再不斷地重現 reproduce

教育部資訊人才培育計畫
71
 若程式是具有多執行緒,分散式網路應用,
平行運算…
Networking apps, multithreading apps,
apps with GUIs… 真實世界的軟體通常屬於此
類
 除錯過程所帶來的 probe effect (利用 print
或 debugger) 不只影響效能,還可能改變執行
緒交互與同步的順序(interleaving)
 程式不見得走到你想要的地方
 錯誤不見得能 reproduce

教育部資訊人才培育計畫
72
 Debugger (System Program)
讓你設中斷點,不用重新編譯整個系統
 在中斷點提供你檢查變數的功能
 提供 call stack 的資訊
 執行過程與 source code 對照
 可以一行一行的執行程式,並立即觀察結果
 增進除錯的效率
 如果你認為不需要用,那你寫的程式都不夠大
與複雜

教育部資訊人才培育計畫
73
 一個重要的系統程式 (system program)
任何開發平台如果要吸引程式開發人員為其寫
程式,Debugger必須要提供的系統程式之一
 一般的平台所提供的系統程式包括
compiler, linker, debugger, assembler …

 debugger 本身是一個複雜的程式
 其最原始的使用模式為 console-mode
(command line)
教育部資訊人才培育計畫
74
 GDB: The GNU Project Debugger
(http://www.gnu.org/s/gdb/)
 能夠debug 用以下的語言寫成的程式
Ada, C, C++, Objective-C, Pascal, Python
(and many other languages),
 Unix based, but it is also ported to
Windows, Mac

 Console mode based
教育部資訊人才培育計畫
75
A debuggee: ex1.c
教育部資訊人才培育計畫
76
打好儲存之後,我們可以在工作站下這樣的指令:
is93007@bsd1:[~]$ gcc -g -o ex1 ex1.c
gcc是大家都應該熟悉的GNU C compiler
• 在命令列中加入-g就是告訴gcc要「含入除錯符號資訊」,若是沒有這個選項,
在除錯時就看不到原始程式碼、變數名稱等等,也就無法進行除錯了。
•
•
•
•
有含除錯訊息的執行檔會比較大
-o 參數後指定的是編譯後的執行檔名稱,最後是原始碼檔案。\
一般而言命令列Compiler 內定是不打開除錯資訊的選項,但是如果compiler
與debugger 等系統工具被整合到一個整合開發環境
(IDE, 如 visual studio, eclipse), 則通常打開的專案是 debug mode
教育部資訊人才培育計畫
77
這就是gdb的啟動畫面與版權聲明,
上面的(gdb)就好像shell的$或%符號,
在這個畫面輸入gdb的命令就可以進行除錯
工作。
教育部資訊人才培育計畫
78
一般而言, 你也可以直接在執行GDB 時,將debuggee 直
接載入,效果一樣
is93007@bsd1:[~]$ gdb ex1
教育部資訊人才培育計畫
79
 在這個例子中我們還沒有設任何中斷點
教育部資訊人才培育計畫
80
教育部資訊人才培育計畫
81
教育部資訊人才培育計畫
82
教育部資訊人才培育計畫
83
當程式停在中斷點時你可以用print (p)印出你
所關心的變數值
(gdb) print e
e = 444
如果每次停在中斷點,你希望直接將你所關心的變
數直接印出來, 請用 display
(gdb) display e
教育部資訊人才培育計畫
84
• 除錯的過程中通常會想要繼續執行程式,因為
通常不可能直接將中斷點設在發生錯誤的地方
指令
說明
continue(c)
繼續執行直到下一個中斷點或結束
step(s)
執行一行程式碼。如果碰到函式會跳進函
式內部去執行
next(n)
執行一行程式碼。不會跳進函式去執行
教育部資訊人才培育計畫
85
 Debugging information 會增加大約10-
20%的 object file 大小
 如果你不在除錯模式底下執行,一般而言
不會減緩程式的執行速度
 不過,Compiler 有個 optimization 的選
項,一般在這個選項底下, debugging
information 會失去作用
教育部資訊人才培育計畫
86
 Yes, 一般而言命令列模式的debugger 使
用起來其實不夠方便(還要背指令),對習
慣視窗世代的學生而言,接受度很低。
 不過,做為主修電腦科學的學生,了解
debugger 是怎麼樣以最原始的形式存在還
是很重要的。
 未來有許許多多非 win-tel 的開發平台。
如果開發平台尚不支援Window GUI,則通
常 debugger 的操作方式就會退回到
console mode 的使用介面
教育部資訊人才培育計畫
87
 為了解決 console mode debugger 不容易
使用的問題,目前整合開發環境都會將
debugger 與 compiler, editor 做整合,
使得除錯過程能更友善
 有時候稱之為 Visual Debugger
教育部資訊人才培育計畫
88
教育部資訊人才培育計畫
89
call stack
variable watch
window
source code
Eclipse
教育部資訊人才培育計畫
90
 請開啟 Eclipse Classic 3.7
 New a project called test
 Enter a helloworld.java as follows
教育部資訊人才培育計畫
91
教育部資訊人才培育計畫
92
 Set break points
 Debug the program (F11)
教育部資訊人才培育計畫
93
call stack
Local
variables
your program
stop here
教育部資訊人才培育計畫
94
教育部資訊人才培育計畫
95
 Click resume to hit the next break point
教育部資訊人才培育計畫
96
Drop to frame
step return
next
step
resume
97
教育部資訊人才培育計畫
教育部資訊人才培育計畫
98
 Drop to frame
 Eclipse 特有的debugger 功能
 用途:你也許將某一個中斷點設在某一個 method 的中
間,而且程式也來到這個中斷點。你想從method 的最
前端重新開始看看怎麼樣到達這個中斷點
 Drop to frame 可以讓你回到這個method 的最開始的
指令
 某一種replay 的功能方便你除錯
教育部資訊人才培育計畫
99
 如果你想暫時的取消 break points 的作
用
教育部資訊人才培育計畫
100
教育部資訊人才培育計畫
101

Set the hit count to
50

Resume the program

Check the value of j
in the for loop
教育部資訊人才培育計畫
102
 Enter a
Boolean
expression
 The breakpoint
will be hit
when the
condition is
true
教育部資訊人才培育計畫
103
 A break point
is hit when
the condition
evaluation
changes.
 So, the break
point will be
hit at
j=0,77,78
教育部資訊人才培育計畫
104
 當你關心的某一樣變數的值被改變,程式
會中斷
 當系統複雜而且龐大,你不曉得到底是誰
的程式或程式的哪一個部份將某個關鍵變
數給改變了。所以你希望除錯器能夠停在
變數被修改的那一行。
 可以算是一種break point
教育部資訊人才培育計畫
105
教育部資訊人才培育計畫
106
教育部資訊人才培育計畫
107
 當程式執行不正確時(不一定是 crash),
如何比較精準地猜測哪部分程式出了問題,
然後開始在適當的地方插入中斷點?
 當你的系統大又複雜,還牽涉到多人合作
時又如何?
 當你的程式沒有良好的模組化時,又如何?
 通常程式發生錯誤的地方,只是結果,而
不是因
教育部資訊人才培育計畫
108
錯誤的源頭
Class or
Method
Class or
Method
error propagation
Class or
Method
錯誤展現的地方
教育部資訊人才培育計畫
109
 Read the source code and find the bugs
 Stupid and inefficient
 Sometimes works because the bug is so 白目
 Step by Step check if each step has problems
 Using steps in a debugger and check variables in each break point
 Doable but time consuming
 Divide and Conquer
 Check middle point results (set break points)
 If the results are correct, the chance that the bug is hidden in the
second half of the program is much higher
 Keep narrow the search by setting break points
 Simplify the test case so that the error can still be
reproduced.
教育部資訊人才培育計畫
110
 善於使用除錯器是一個程式開發人員必備
的技能
 但是如果你發現你必須花費很長的時間才
能找到一個bug的源頭
 這可能表示
你的 coding 習慣不良,
 程式的模組性(或物件導向設計)太差所以bug容
易躲藏


教育部資訊人才培育計畫
111
 最好的除錯技巧是

讓錯誤自己早一點跑出來
 But HOW?
教育部資訊人才培育計畫
112
我們能否早一點讓
bug 自顯於最接近
錯誤源頭的地方
錯誤的源頭
Class or
Method
Class or
Method
error propagation
Class or
Method
錯誤展現的地方
教育部資訊人才培育計畫
113
馬路如虎口
當紅綠燈從紅燈變成綠燈時,你會奮勇的往
前衝嗎?
教育部資訊人才培育計畫
114
 In school, mostly you complete your programming work
alone.
 In real world, you work with others to complete a product
 The stupidest phenomenon








You join all your source codes
Build
Run
Crash
大眼瞪小眼
Accuse each other
拱出一人專責debugging
A great amount of time is spent until who is to blame is settled.
115
教育部資訊人才培育計畫
116
太空船或一班船鑑如何防止船體受損時爆炸擴散到其他部分?
教育部資訊人才培育計畫
117
 An assertion is code that’s used during
development – typically exists through alpha
testing and beta testing and removed in
release
 It is instrumented into your code, which is
called instrumentation
 Assertions are especially useful in large,
complicated programs and in high reliability
programs
118
 In standard C, you can use
#include <assert.h>
void foo(int x) {
assert(x > 10) ;
}
 You can also define your own ASSERT
#define ASSERT(condition, message) { \
if (!(condition)) { \
LogError(“Assertion Failed:”, \
#condition, message) ; \
exit(EXIT_FAILURE);\
}\
}
119
NDEBUG is defined
in release build
#ifdef NDEBUG
#define assert(_Expression)
((void)0)
#else
#ifdef __cplusplus
extern "C" {
#endif
_CRTIMP void __cdecl _wassert(_In_z_ const wchar_t * _Message, _In_z_ const
wchar_t *_File, _In_ unsigned _Line);
#ifdef __cplusplus
}
#endif
#define assert(_Expression) (void)( (!!(_Expression)) ||
(_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )
#endif /* NDEBUG */
教育部資訊人才培育計畫
120
 在現在的整合開發環境中當你的程式中止
在 ASSERT 時,你的整合開發環境允許你
觀察中止的當下的 local 變數,call
stack 等等資訊,方便你來除錯
教育部資訊人才培育計畫
121
 In Java
 assert denominator != 0 : “denominator is
unexpectedly equal to 0.”
 Example
……
assert allcost !=0 : “assert failed: in foo(), allcost is
unexpectedly equal to 0.” ;
averagecost = this.salary/ allcost ;
122
 That an input parameter's value falls within its
expected range (or an output parameter's value
does)
void p(int dir, int velocity) {
assert(dir >=0 && dir < 4 ) ;
assert(velocity >= 0 && velocity < 10);
………………
}
 That a file or stream is open (or closed) when a routine
begins executing (or when it ends executing)
void p(FILE *fp, string &msg) {
assert(fp != null) ;
assert(msg.getLength() >= 1 && msg.getLength() <= 255);
}
123







That a file or stream is at the beginning (or end) when a routine begins
executing (or when it ends executing)
That a file or stream is open for read-only, write-only, or both read and write~ I .
That the value of an input-only variable is not changed by a routine
That a pointer is non-null
That an array or other container passed into a routine can contain at least XI
number of data element
That a table has been initialized to contain real values
void p(Object table[], int no) {
assert(no != 0) ;
for (int i=0;i< no; i++) {
assert(table[i] != null) ;
assert(table[i].getval() >= -1 && table[i].getval() <= 1) ;
}
That a container is empty (or full) when a routine begins executing (or when it
finishes)
That the results from a highly optimized, complicated routine match the results
from a slower but clearly written routine 1
124
 When you left some part of the code to be dealt
later or refined later.
If (something) {
…………. // do some normal things
} else { // right now, it should not happen
// you are not sure how this can
// be reached.
assert(false); // “under construction”
}
125
 Assertion are used to handle errors
that should never occurs in the code
 Error handling (Exception Handling)
is handing error you expect to occur.
Such as file open errors
 Assertion 的程式碼在 release 中會被移
除,但是 Error handling 的程式碼是系
統本身的一部分
 Assertion 是除錯的輔助技術
126
127
 The good habits and good discipline
Never assume your data file is correct. (就算code
與檔案都是你自己一個人完成)
 If you assume it, sometime it causes you days in
debugging but actually your program works
correctly.
 Data file can be corrupted for different kind of
reasons which you can never know and expect

128
錯誤的源頭
assert
Class or
Method
Class or
Method
Class or
Method
assert
assert
assert
assert
錯誤展現的地方
教育部資訊人才培育計畫
129
 Assertion 可以幫你提早警示程式的錯誤,
讓你更接近問題的源頭
 Assertion 多多益善,有賴習慣的養成
教育部資訊人才培育計畫
130
 請先思考一個簡單的品質問題
如果一個產品包含了100個零件,而每個零件的品質參差
不齊,請問整合這些零件的產品品質如何?
如果在生產過程中,每個元件加入嚴謹的品質控管與量
測,請問生產出來的產品,品質會如何?
教育部資訊人才培育計畫
131
元件成本低,品質差不保證
教育部資訊人才培育計畫
132
如果在整合前,每一個元件 (class, object,
component, library) 都做了徹底的品質
控管,整合之後的軟體問題自然會少
教育部資訊人才培育計畫
133
光電精密量測
在許多工程領域,精密量測是非常重要的,因為沒有量測就沒有品質
教育部資訊人才培育計畫
134
 軟體開發的新趨勢

Unit Testing (use xUnit framework)
 Agile vs Waterfall (CMMI)
 Test enforced programming
Industry gradually adopt this approach
 The education of the new approach has been slow

教育部資訊人才培育計畫
135
develop
Design
Test Magic
Manual Tests
Exploratory Tests
Automated Tests
tools
Test Magic
Software engineer
Test engineer
 Original was for SmallTalk
 Kent
Beck and Erich Gamma
 Ported to Various languages and platforms
 JUnit,
CppUnit, DUnit, VBUnit, RUnit, PyUnit, Sunit,
HtmlUnit, …
 Good list at www.xprogramming.com
 Standard test architecture
 1. Write a test




Test-driven development always begins with writing a test.
2. Run all tests and see the new one fail
This validates that the test harness is working correctly and that the new test
does not mistakenly pass without requiring any new code.
3. Write some code
The next step is to write some code that will pass the test. The new code
written at this stage will not be perfect and may, for example, pass the test in
an inelegant way. That is acceptable as later steps will improve and hone it. It
is important that the code written is only designed to pass the test, no
further (and therefore untested) functionality must be predicted and
'allowed for' at any stage.
4. Run the automated tests and see them succeed
If all test cases now pass, the programmer can be confident that the code
meets all the tested requirements. This is a good point from which to begin
the final step of the cycle.
5. Refactor to remove duplication
Now the code can be cleaned up as necessary. By re-running the test cases
the developer can be confident that refactoring is not damaging any existing
functionality. The concept of removing duplication is an important aspect of
any software design. In this case, however, it also applies to removing any
141
public class MoneyTest extends TestCase {
//…
public void testSimpleAdd() {
Money m12CHF= new Money(12, "CHF"); // (1)
Money m14CHF= new Money(14, "CHF");
Money expected= new Money(26, "CHF");
Money result= m12CHF.add(m14CHF); // (2)
Assert.assertTrue(expected.equals(result));
// (3)
}
}
(1) Creates the objects we will interact with during the test. This testing
context is commonly referred to as a test's fixture. All we need for
the testSimpleAdd test are some Money objects.
(2) Exercises the objects in the fixture.
(3) Verifies the result
142
 xUnit test framework 是軟體開發近幾年
來的一個趨勢
 Programmer 為了確保元件的正確性,必須
寫測試
 單元測試可以自動化,所以可以很有效率
的偵測程式的修改是否弄壞了舊有的功能
 單元測試是一種 regression testing
教育部資訊人才培育計畫
143
 assert 可以確保元件之間的互動,符合
contract,早一步攔截有問題的run,避免
錯誤傳遞,排除整合所發生的複雜難解的
bug
 單元測試(unit testing)的施行雖然不能
確保整合之後沒有 bug,不過它可以先期
把關元件的品質,進而減少複雜而難解bug
的發生,讓許多 bug 早期發現。
 兩者都是儘量讓錯誤早期發現,使得除錯
能更有效率
教育部資訊人才培育計畫
144
 請到
http://140.115.155.110/trac/bugreport
 裡面有幾個簡單的Java 程式以及其功能的
說明,但是這些程式都是錯的
 請利用 Eclipse 的debugger 來找出錯誤
教育部資訊人才培育計畫
145
 3個練習題的正確答案在
http://140.115.155.110/trac/bugreport
/wiki/HereWeAre
教育部資訊人才培育計畫
146