Ch ng Chín - Debugươ
Bugs là nh ng l i l m c a program mà ta phát hi n khi ch y nó. Debug là công vi c lo i t t c
nh ng l i l m trong ch ng trình đ nó ch y êm xuôi trong m i hoàn c nh. ươ
Thông th ng mu n fix m t cái bug nào tr c h t ta ph i tìm hi u lý do khi n nó xu t hi n. M tườ ướ ế ế
khi đã bi t đ c duyên c r i ta s nghĩ ra cách gi i quy t. Nói chung, có hai lo i bugs: ế ượ ế
1. Ho c là program không làm đúng chuy n c n ph i làm vì programmer hi u l m
Specifications hay đ c cho tin t c sai l c, ho c là program b sót chi ti t c n ph i có. Tr ngượ ế ườ
h p n y ta gi i quy t b ng cách gi m thi u s hi u l m qua s nâng c p kh năng truy n ế
thông.
2. Program không th c hi n đúng nh ý programmer mu n. T c là programmer mu n m t đàng ư
mà b o ch ng trình làm m t ngã vì vô tình không vi t l p trình đúng cách. Tr ng h p n y ta ươ ế ườ
gi i quy t b ng cách dùng nh ng Software Tools (k c ngôn ng l p trình) thích h p, và có ế
nh ng quá trình làm vi c có h th ng.
Trong hãng xe h i ng i ta dùng t ơ ườ Quality Control đ nói đ n vi c ch ra chi c xe không có l i ế ế ế
l m gì c . Đ đ t m c tiêu y, ch ng nh ng c n có ng i ki m ph m mà chính các nhân viên l p ườ
ráp th n tr ng đ công vi c chính c a ng i ki m ph m là xác nh n k t qu t t ch không ph i ườ ế
tìm l i l m.
Có nhi u y u t nh h ng đ n ch t l ng c a m t program nh ch c năng c a program, c u ế ưở ế ượ ư
trúc c a các b ph n, k thu t l p trình và ph ng pháp debug. Debug không h n n m giai đo n ươ
cu i c a d án mà tùy thu c r t nhi u vào các y u t k tr c trong m i giai đo n tri n khai. ế ướ
Ch c năng c a ch ng trình (Program Specifications) ươ
D u program l n hay nh , tr c h t ta ph i xác nh n rõ ràng và t m nó c n ph i làm gì, bao nhiêu ướ ế
ng i dùng, m ng nh th nào, database l n bao nhiêu, ph i ch y nhanh đ n m c nào .v.v..ườ ư ế ế
Có nhi u ch ng trình ph i b thay đ i n a ch ng vì programmers hi u l m đi u khách hàng ươ
mu n. Kh nh t là lúc g n giao hàng m i khám phá ra có nhi u đi m trong ch ng trình khách ươ
mu n m t đàng mà ta làm m t ngã. Do đó trong s liên h v i khách hàng ta c n ph i h i đi, h i
l i, ph n h i v i khách hàng nhi u l n đi u ta hi u b ng th t , tài li u, đ khách xác nh n là ta ư
bi t đúng ý h tr c khi xúc ti n vi c thi t k ch ng trình. N u sau n y khách đ i ý, đó là quy nế ướ ế ế ế ươ ế
c a h , nh ng h ph i tr ti n thay đ i ( ư variation).
C u trúc các b ph n
Program nào cũng có m t ki n trúc t ng t nh m t căn nhà. M i b ph n càng đ n gi n càng t t ế ươ ư ơ
và cách ráp các b ph n ph i nh th nào đ ta d th . Trong khi thi t k ta ph i bi t tr c nh ng ư ế ế ế ế ướ
y u đi m c a m i b ph n n m đâu đ ta chu n b cách th chúng. Ta s không h tin b ph nế
nào hoàn h o cho đ n khi đã th nó, dù nó đ n s đ n đâu. ế ơ ơ ế
N u ta mu n dùng m t k thu t gì trong m t hoàn c nh nào mà ta không bi t ch c nó ch y khôngế ế
thì nên th riêng r nó tr c. Ph ng pháp y đ c g i là ướ ươ ượ Prototype.
Ngoài ra, ta cũng nên k ho ch cho nh ng tr ng h p b t ng , đi n hình là bad data - khi user b mế ườ
lung tung hay database ch a rác r n. ế
N u ch ng trình ch y trong ế ươ real-time (t c là data thu nh p qua Serial Comm Port, Data
Acquisition Card hay m ng), b n c n ph i l u ý nh ng tr ng h p khác nhau tùy theo vi c gì x y ư ườ
ra tr c, vi c gì x y ra sau. Lúc b y gi Logic c a ch ng trình s tùy thu c vào tr ng thái (ướ ươ State)
c a data. T t nh t là nghĩ đ n nh ng ế Scenarios (di n ti n c a nh ng hoàn c nh) đ có th th ế
t ng giai đo n và tình hu ng.
Ngày nay v i k thu t Đ i T ng, giai đo n thi t k n y là lúc quy t đ nh các Data Structures ượ ế ế ế
(tables, records ..v.v.) và con s Forms v i Classes. Nh r ng m i Class g m có m t Data Structure
và nh ng Subs/Functions/Properties làm vi c (operate) trên data y. Data structure ph i ch a đ y đ
nh ng chi ti t (data fields, variables) ta c n. K đó là nh ng cách ch ng trình process data. ế ế ươ
Subs/Functions nào có th cho bên ngoài g i thì ta cho nó Public, còn nh ng Subs/Functions khác
hi n h u đ ph c v bên trong class thì ta cho nó Private.
K thu t l p trình
Căn b n c a programmers và các thói quen c a h r t quan tr ng. Nói chung, nh ng ng i h p ườ
t p, nh y vào vi t ch ng trình tr c khi suy nghĩ hay cân nh c chính ch n thì sau n y bugs lòi ra ế ươ ướ
kh p n i là chuy n t nhiên. ơ
Dùng Subs và Functions
N u giai đo n thi t k ki n trúc c a ch ng trình ta chia ra t ng Class, thì khi l p trình ta l iế ế ế ế ươ
thi t k chi ti t v Subs, Functions .v.v.., m i th s c n ph i th nh th nào. N u ta có th chiaế ế ế ư ế ế
công vi c ra t ng giai đo n thì m i giai đo n có th mà m t call đ n m t ế Sub. Th gì c n ph i
tính ra hay l y t n i khác thì có th đ c th c hi n b ng m t ơ ượ Function.
Thí d nh công vi c trong m t ti m gi t i có th g m có các b c sau: ư ướ
1. Nh n hàng
2. Phân chia t ng lo i
3. T y
4. Gi t
5. i
6. Vô bao
7. Tính ti n
8. Giao hàng
Trong đó các b c 1,2,6 và 8 có th là nh ng Subs. Còn các b c 3,4,5 và 7 nh ng Functions, thíướ ướ
d nh khi ta giao cho ư Function Gi t m t cái áo d ta s l y l i m t cái áo s ch. ơ
Nh r ng đi m khác bi t chính gi a m t Sub và m t Function là Function cho ta m t k t qu ế
không làm thay đ i nh ng parameters ta đ a cho nó. Trong khi đó, d u r ng Sub không cho ta gìư
m t cách rõ ràng nh ng nó có th thay đ i tr s (value) c a b t c parameters nào ta pass cho nó ư
ByRef. Nh c l i là khi ta pass m t parameter ByVal cho m t Sub thì gi ng nh ta đ a m t ư ư copy
(b n sao) c a variable đó cho Sub, Sub có th s a đ i nó nh ng nó s b b qua, không nh h ng ư ưở
gì đ n ếoriginal (b n chính) variable.
Ng c l i khi ta pass m t parameter ượ ByRef cho m t Sub thì gi ng nh ta đ a b n chính c a ư ư
variable cho Sub đ nó có th s a đ i v y.
Do đó đ tránh tr ng h p vô tình làm cho tr s m t variable b thay đ i vì ta dùng nó trong m t ườ
Sub/Function b n nên dùng ByVal khi pass nó nh m t parameter vào m t Sub/Function. ư
Th t ra, b n có th dùng ByRef cho m t parameter pass vào m t Function. Trong tr ng h p đó dĩ ườ
nhiên variable y có th b s a đ i. Đi u n y g i là ph n ng ph ( side effect), vì bình th ng ít aiườ
làm v y. Do đó, n u b n th t s mu n v t ngoài qui c thông th ng thì nên Comment rõ ràng ế ượ ướ ườ
đ c nh cáo ng i s đ c ch ng trình b n sau n y. ườ ươ
Ngoài ra, m i programmer th ng có m t ườ Source Code Library c a nh ng Subs/Functions ng ý. ư
B n nên dùng các Subs/Functions trong Library c a b n càng nhi u càng t t, vì chúng đã đ c th ượ
nghi m r i.
Đ ng s Error
M i khi ch ng trình có m t Error, ho c là ươ Compilation Error (vì ta vi t code không đúng vănế
ph m, ng v ng), ho c là Error trong khi ch y ch ng trình, thì b n không nên s nó. Hãy bình ươ
tĩnh đ c cái Error Message đ xem nó mu n nói gì. N u không hi u ngay thì đ c đi đ c l i vài l n ế
và suy nghi m xem có tìm đ c mách n c nào không. Ngh programming c a chúng ta s g p ượ ướ
Errors nh ăn c m b a, nên b n ph i t p bình tĩnh đ i di n v i chúng.ư ơ
Dùng Comment (Chú thích)
Lúc vi t code nh thêm ế Comment đ y đ đ b t c khi nào tr l i đ c đo n code y trong t ng ươ
lai b n không c n ph i d a vào tài li u nào khác mà có th hi u ngay l p t c m c đích c a m t
Sub/Function hay đo n code.
Nh th không nh t thi t b n ph i vi t r t nhi u Comment nh ng h có đi m nào khác th ng, bíư ế ế ế ư ườ
hi m thì b n c n thông báo và gi i thích t i sao b n làm cách y. Có th sau n y ta khám phá ra
đo n code có bugs; lúc đ c l i có th ta s th y d u r ng ý đ nh và thi t k đúng nh ng cách l p ế ế ư
trình có ph n thi u soát ch ng h n. ế
Tính ra trung bình m t programmer ch làm vi c 18 tháng m i ch . T c là, g n nh ch c ch n ư
code b n vi t s đ c ng i khác đ c và b o trì ( debug và thêm b t). Do đó, code ph i càng đ n ế ượ ườ ơ
gi n, d hi u càng t t. Đ ng lo ng i là ch ng trình s ch y ch m hay chi m nhi u b nh , vì ươ ế
ngày nay computer ch y r t nhanh và b nh r t r . Khi nào ta th t s c n ph i quan tâm v v n
t c và b nh thì đi u đó c n đ c thi t k c n th n ch không ph i d a vào nh ng ti u x o v ượ ế ế
l p trình.
Đ t tên các variables có ý nghĩa
Kh nh t là làm vi c v i các variables có tên v n t t nh K, L, AA, XY. Ta không có m t chút ý ư
ni m chúng là ai, hi n h u đ làm gì. Thay vào đó, n u ta đ t các tên variables nh ế ư
NumberOfItems, PricePerUnit, Discount .v.v.. thì s d hi u h n. ơ
M t trong nh ng bugs khó th y nh t là ta dùng cùng m t tên cho local variable (variable declared
trong Sub/Function) và global variable (variable declared trong Form hay Basic Module). Local
variable s che đ y global variable cùng tên, nên n u b n mu n nói đ n global variable trong hoàn ế ế
c nh y b n s dùng l m local variable.
Dùng Option Explicit
B n nên trung tín dùng Option Explicit đ u m i Form, Class hay Module. N u có variable nào ế
đánh v n tr t VB6 IDE s cho b n bi t ngay. N u b n không dùng Option Explicit, m t variable ế ế
đánh v n tr t đ c xem nh m t variable m i v i giá tr 0 hay "" (empty string). ượ ư
Nói chung b n nên th n tr ng khi assign m t data type cho m t variable v i data type khác. B n
ph i bi t rõ b n đang làm gì đ kh i b ph n ng ph (side effect). ế
Desk Check
Ki m l i code tr c khi compile. Khi ta compile code, n u không có error ch có nghĩa là Syntax ướ ế
c a code đúng, không có nghĩa là logic đúng. Do đó ta c n ph i bi t ch c là code ta vi t s làm ế ế
đúng đi u ta mu n b ng cách đ c l i code tr c khi compile nó l n đ u tiên. Công vi c n y g i ướ
Desk Check (Ki m trên bàn). M t ch ng trình đ c Desk Checked k s c n ít debug và ch a ít ươ ượ
bugs không ng tr c. Lý do là m i scenarios đã đ c tiên li u chu đáo. ướ ượ
So n m t Test Plan
Test Plan li t kê t t c nh ng gì ta mu n th và cách th chúng. Khi th theo Test Plan ta s khám
phá ra nh ng bug và tìm cách lo i chúng ra. H s ghi l i l ch s c a Test Plan (tr c tr c gì x y ra, ơ
b n đã dùng bi n pháp nào đ gi i quy t) s b ích trên nhi u ph ng di n. Ta s h c đ c t ế ươ ượ
kinh nghi m Debug và bi t rõ nh ng th gì trong d án đã đ c th theo cách nào. ế ượ
X Error lúc Run time
Khi EXE c a m t ch ng trình vi t b ng VB6 đang ch y, n u g p Error, nó s hi n th m t ươ ế ế Error
Dialog cho bi t lý do v n t c. Sau khi b n click OK, ch ng trình s ng ng. N u b n ch yế ươ ư ế
ch ng trình trong VB6 IDE, b n có d p b o program ng ng trong source code ch có Error b ngươ
cách b m button Debug trong Error Dialog. Ti p theo đó b n có th tìm hi u tr s các variables đế
đoán nguyên do c a Error. Do đó, n u b n b t đ u cho dùng m t program b n vi t trong s , n u ế ế ế
ti n thì trong vài tu n đ u, thay gì ch y EXE c a ch ng trình, b n ch y source code trong VB6 ươ
IDE. N u có bug nào x y ra, b n có th cho program ng ng trong source code đ debug.ế
Khi b n dùng statement:
On Error Resume Next
thì t ch đó tr đi, n u ch ng trình g p Error, nó s b qua (ignore) hoàn toàn. Đi m n y ti n ế ươ
ch giúp ch ng trình EXE c a ta tránh b té cái ch r i bi n m t, r t là "quê" v i khách hàng. ươ ế
Nh ng nó cũng b t l i là khi khách hàng cho hay h g p nh ng tr ng h p l , không gi i thíchư ườ
đ c (vì Error b ignored mà không ai đ ý), thì ta cũng bí luôn, có th không bi t b t đ u t đâu đượ ế
debug. Do đó, dĩ nhiên trong lúc debug ta không nên dùng nó, nh ng tr c khi giao cho khách hàngư ướ
b n nên cân nh c k tr c khi dùng. ướ
Dùng Breakpoints
Cách hay nh t đ theo dõi execution c a program là dùng Breakpoint đ làm cho program ng ng
l i m t ch ta mu n trong code, r i sau đó ta cho program b c t ng b c. Trong d p n y ta s ướ ướ
xem xét tr s c a nh ng variables đ coi chúng có đúng nh d đ nh không. ư
B n đoán tr c execution s đi qua ch nào trong code, ch n m t ch thích h p r i click bên trái ướ
c a hàng code, ch d u ch m tròn đ nh trong hình d i đây: ư ướ
N u b n click lên d u ch m tròn đ m t l n n a thì là h y b nó. M t cách khác đ đ t m tế
breakpoint là đ editor cursor lên hàng code r i b m F9. N u b n b m F9 l n n a khi cursor n mế
trên hàng đó thì là h y b break point.
Lúc program đang d ng l i, b n có th xem tr s c a m t variable b ng cách đ cursor lên trên
variable y, tooltip s hiên ra nh trong hình d i đây: ư ướ
Có m t s chuy n khác b n có th làm trong lúc n y. B n có th n m d u ch m tròn đ kéo
(drag) nó ng c lên m t hay nhi u hàng code đ nó s execute tr l i vài hàng code. B n choượ
program execute t ng hàng code b ng cách b m F8. Menu command t ng đ ng v i nó là ươ ươ Debug
| Step Into. S có lúc b n không mu n program b c vào bên trong m t Sub/Function mà mu n ướ
vi c execute m t Sub/Function nh m t b c đ n gi n. Trong tr ng h p đó, b n dùng Menu ư ướ ơ ườ
command Debug | Step Over hay Shift-F8.
Nh là đ cho program ch y l i b n b m F5, t ng đ ng v i Menu command ươ ươ Run | Continue.
Có khi b n mu n program ng ng gi a m t For Loop khi Iterator value có m t tr s khá l n. N u ế
ta đ s n m t breakpoint đó r i c b m F5 nhi u l n thì h i b t ti n. Có m t mánh l i là dùng ơ
m t IF statement đ th khi Iterator value có tr s y thì ta ng ng breakpoint t i statement Beep
(thay gì statement Print ICounter) nh trong hình d i đây:ư ướ
Mu n h y b m i breakpoints b n dùng Menu command Debug | Clear All Breakpoints.
Đ ti n vi c debug, b n có th dùng Debug Toolbar b ng cách hi n th nó v i Menu command
View | Toolbars | Debug