สวัสดีและยินดีต้อนรับ.
ในการบรรยายนี้ ฉันต้องการพูดคุยเกี่ยวกับการดีบั๊ก
นี่เป็นแนวคิดที่สำคัญมากที่คุณต้องเข้าใจโดยเฉพาะ คุณต้องเข้าใจเครื่องมือบางอย่างและวิธีการบางอย่างที่คุณสามารถใช้เพื่อค้นหาและแก้ไขจุดบกพร่อง
ดังนั้นการดีบักจึงเป็นกระบวนการค้นหาและแก้ไขข้อผิดพลาดในโปรแกรม
มักจะเกิดข้อผิดพลาดทางตรรกะ
และฉันจะบอกคุณถึงความแตกต่างระหว่างข้อผิดพลาดทางตรรกะและไวยากรณ์ แต่อาจรวมถึงข้อผิดพลาดทางไวยากรณ์ของคอมไพเลอร์ด้วย
เป็นกระบวนการทั้งหมดสำหรับข้อผิดพลาดทางไวยากรณ์
การดีบักคือการทำความเข้าใจสิ่งที่คอมไพเลอร์กำลังบอกคุณ
คุณต้องการมุ่งเน้นไปที่การแก้ไขปัญหาแรกที่ตรวจพบเสมอ
ฉันต้องการอธิบายถึงข้อผิดพลาดและคำเตือนของคอมไพเลอร์ทั่วไปที่คุณอาจได้รับ แต่สิ่งหนึ่งที่คุณต้องการทราบเกี่ยวกับคอมไพเลอร์อยู่เสมอก็คือ
คอมไพเลอร์อาจให้ข้อผิดพลาดจำนวนหนึ่งแก่คุณ
คุณต้องการเน้นที่ข้อผิดพลาดแรกเสมอ เนื่องจากข้อผิดพลาดแรกนั้นอาจส่งผลให้เกิดข้อผิดพลาดอื่นๆ
ดังนั้นจึงอาจทำให้เข้าใจผิดได้อย่างมากหากคุณเห็นข้อผิดพลาด 5 ข้อใน a ในโปรแกรมที่คอมไพเลอร์บอกคุณ คุณอาจมีข้อผิดพลาดเพียงข้อเดียว
และข้อผิดพลาดแรกนั้นอาจทำให้เกิดข้อผิดพลาดอื่นๆ
ดังนั้นสิ่งสำคัญคือต้องดูที่ข้อผิดพลาดอันดับแรกและแก้ไขข้อผิดพลาดนั้นก่อนเสมอ
ในตัวอย่างง่ายๆ นี้ เรามีข้อผิดพลาดหลายข้อในโค้ดนี้
เราไม่มี
เราไม่มีวงเล็บเริ่มต้นด้านซ้าย วงเล็บปีกกา
เราไม่มีเครื่องหมายอัฒภาค
เรากำลังส่งคืนสตริง
และเมื่อเราบันทึกสิ่งนี้และเราไปคอมไพล์มัน และคุณเห็นข้อผิดพลาดสีแดง
เมื่อเราคอมไพล์ มันบอกเราว่าเรามีข้อผิดพลาดสามข้อ
คุณไม่ต้องการเพียงแค่เลือกข้อผิดพลาดสุดท้ายในบรรทัดที่ 7 แม้ว่าในกรณีนี้จะเป็นข้อผิดพลาดจริงก็ตาม
คุณต้องการแก้ไขข้อผิดพลาดแรกเสมอ
คุณจึงเห็นข้อผิดพลาดแรกแสดงอยู่ที่นี่ และคุณแก้ไขข้อผิดพลาดแรก จากนั้นจึงคอมไพล์ใหม่และเรียกใช้อีกครั้ง
แต่เหตุผลที่ต้องทำเช่นนี้ก็เพื่อแก้ไขข้อผิดพลาดระดับบนสุดเท่านั้น เนื่องจากข้อผิดพลาดนั้นอาจทำให้เกิดปัญหาอื่นๆ
ดังนั้นให้โฟกัสที่การแก้ไขข้อบกพร่องในครั้งแรกเสมอ และกระบวนการค้นหาและแก้ไขข้อบกพร่องอาจซับซ้อนมาก
ตั้งแต่การค้นหาข้อผิดพลาดง่ายๆ ไปจนถึงการรวบรวมข้อมูลจำนวนมากเพื่อการวิเคราะห์
ทุกอย่างขึ้นอยู่กับ
บางครั้งคุณไม่มีข้อมูลใดๆ ให้กับคุณ ยกเว้นการบันทึก และในกรณีนี้ คุณต้องวิเคราะห์สิ่งต่างๆ
บางครั้งคุณจะมีข้อบกพร่องที่ไม่สามารถทำซ้ำได้
คุณไม่สามารถทำซ้ำได้เพราะมันเกิดขึ้นในโอกาสที่หายากเช่นนี้
โดยปกติจะเป็นเวลาที่คุณต้องวิเคราะห์บันทึกหรือการเปลี่ยนแปลงบางอย่าง
ความสามารถในการดีบักโดยโปรแกรมเมอร์เป็นทักษะที่จำเป็น
เป็นทักษะการแก้ปัญหาที่สามารถช่วยคุณประหยัดเวลาและเงินได้มหาศาล
ดังนั้นจึงเป็นทักษะที่สำคัญในการเรียนรู้
เป็นทักษะที่สำคัญในการพัฒนา
ต้องใช้เวลาฝึกฝน
คุณจะไม่เพียงแค่ไปหามัน ไม่ใช่แค่จะมาหาคุณ
มีเทคนิคบางอย่างที่คุณสามารถนำไปใช้และวิธีการที่คุณสามารถนำไปใช้เพื่อให้คุณแก้จุดบกพร่องได้ดีขึ้น
ฉันรู้จักนักพัฒนาจำนวนไม่น้อยที่เขียนซอฟต์แวร์เขียนโค้ดได้ดี
พวกเขาเข้าใจภาษาเป็นอย่างดี แต่ทักษะการแก้ไขข้อบกพร่องของพวกเขาแย่มาก
พวกเขาอาจได้รับข้อบกพร่องและความตั้งใจแรกในการแก้ไขข้อบกพร่องนั้นเป็นเรื่องที่ผิดแผนจริงๆ
และอีกครั้ง สิ่งนี้มาพร้อมกับการฝึกฝน
คุณจะเก่งขึ้นเรื่อย ๆ ในการดีบักและเข้าใจวิธีค้นหาและแก้ไขปัญหา แต่ก็เป็นสิ่งที่คุณต้องเรียนรู้เช่นกัน
ขั้นตอนการบำรุงรักษาเป็นขั้นตอนที่แพงที่สุดของวงจรชีวิตซอฟต์แวร์
ขั้นตอนการบำรุงรักษาคือหลังจากที่คุณปล่อยผลิตภัณฑ์และตอนนี้คุณต้องบำรุงรักษา
การบำรุงรักษาหมายถึงการแก้ไขข้อบกพร่องใหม่ ๆ ที่เข้ามาและเพิ่มคุณลักษณะใหม่ ๆ
ตัวอย่างเช่น เมื่อ Windows ออกระบบปฏิบัติการใหม่ เช่น Windows 10 ระบบจะผลิตซอฟต์แวร์นั้นไม่เสร็จ
มันจะอยู่นอกสนามเป็นเวลาสิบปี
และยังคงเป็นความรับผิดชอบของ Microsoft เมื่อมีข้อบกพร่องใหม่เข้ามาหรือพบข้อบกพร่องใหม่สำหรับซอฟต์แวร์นั้นเพื่อแก้ไข
และนั่นคือเหตุผลที่พวกเขาผลักดันการอัปเดตอัตโนมัติและทำสิ่งต่างๆ เช่นนั้น
จากนั้นพวกเขาจะสังเกตเห็นว่าระบบปฏิบัติการจะออกคุณสมบัติใหม่เมื่อตลาดเปลี่ยนแปลงและเทคโนโลยีเปลี่ยนไป
การบำรุงรักษาจึงสำคัญมาก
ด้วยเหตุนี้ การค้นหาและแก้ไขจุดบกพร่องจึงมีความสำคัญมาก
เข้าใจว่าข้อบกพร่องเป็นสิ่งที่หลีกเลี่ยงไม่ได้
ซอฟต์แวร์ทั้งหมดมีข้อผิดพลาด
ไม่มีใครสามารถเขียนโค้ดที่สมบูรณ์แบบได้ และไม่จำเป็นต้องเกี่ยวกับการเขียนโค้ดที่สมบูรณ์แบบด้วยซ้ำ
เป็นเพียงสิ่งที่เปลี่ยนแปลงไปตามกาลเวลา
นั่นอาจส่งผลให้เกิดข้อบกพร่องเช่นกัน
คุณต้องเข้าใจว่าเพียงเพราะซอฟต์แวร์มีจุดบกพร่องไม่ได้หมายความว่าโค้ดนั้นเขียนได้ไม่ดี
มันเป็นสิ่งที่หลีกเลี่ยงไม่ได้
ดังนั้นจึงไม่เป็นไรที่จะมีข้อบกพร่อง เมื่อคุณพบและแก้ไขข้อบกพร่องเหล่านั้น มันจะยิ่งดีขึ้นเพราะคุณรู้สึกเหมือนกำลังทำบางสิ่งให้สำเร็จ
ปัญหาที่พบบ่อย
และเราจะพูดถึงเพิ่มเติมเกี่ยวกับปัญหาเฉพาะที่เกี่ยวข้องกับการมองเห็น
แต่ปัญหาทั่วไปเมื่อคุณพยายามดีบักคือข้อผิดพลาดทางตรรกะ
ข้อผิดพลาดทางลอจิกเกี่ยวข้องกับสิ่งที่ตรงกันข้ามกับข้อผิดพลาดทางไวยากรณ์ที่โค้ดของคุณคอมไพล์จริง
มันใช้งานได้ แต่ไม่ได้ทำในสิ่งที่ตั้งใจจะทำ
ดังนั้นจึงมีตรรกะหรือฟังก์ชันการทำงานบางอย่างที่ไม่ถูกต้อง
บางทีคุณอาจมีคำสั่ง IF และคุณกำลังกระโดดลงไปในคำสั่ง if ในเงื่อนไขที่ไม่ถูกต้อง
บางทีคุณอาจมีการวนซ้ำและการวนซ้ำไม่ได้ดำเนินการตามจำนวนครั้งที่ถูกต้อง หรือคุณเรียงลำดับไม่ถูกต้อง
ฟังก์ชั่นใช้งานไม่ได้ แต่คอมไพเลอร์บอกว่า เฮ้ ทุกอย่างดูดี
นี่คือตัวอย่างของข้อผิดพลาดทางตรรกะ
ข้อผิดพลาดทางตรรกะคือจุดที่ไวยากรณ์ถูกต้อง แต่ผลลัพธ์ที่ต้องการไม่ถูกต้องเนื่องจากปัญหาทางตรรกะบางประเภท
ดังนั้นในโค้ดนี้ คุณจะเห็นว่า for วนซ้ำมีเครื่องหมายอัฒภาคต่อท้าย ซึ่งถูกต้องตามวากยสัมพันธ์
แต่คุณคาดหวังว่าสิ่งนี้จะวนซ้ำห้าครั้ง
แต่มันไม่ใช่
จะใช้เวลาทำงานเพียงครั้งเดียวเท่านั้น
ดังนั้น หากเราพูดว่า build และเราสร้างโปรเจกต์นี้ เราจะเห็นคำเตือน ซึ่งเป็นสิ่งที่ดีและคุณควรแก้ไขคำเตือนทั้งหมดของคุณเสมอ
แต่ก็รวบรวมได้สำเร็จ
ดังนั้น เมื่อเรารันโปรเจกต์นี้ คุณจะสังเกตเห็นว่าจริงๆ แล้วโปรเจ็กต์นี้รันเพียงครั้งเดียวและพิมพ์
Hello World ออกมาหนึ่งครั้ง
นี่คือตัวอย่างข้อผิดพลาดทางตรรกะ
ข้อผิดพลาดทางไวยากรณ์เกี่ยวข้องโดยตรงกับคอมไพเลอร์
สิ่งเหล่านี้ไม่เป็นไปตามกฎเกณฑ์ของภาษา
คุณไม่มีเครื่องหมายอัฒภาคที่ส่วนท้ายของคำสั่ง
คุณไม่มีตอนจบใช่ไหม?
วงเล็บด้านซ้าย, วงเล็บ
คุณไม่มีวงเล็บ
คุณไม่ได้ใช้คีย์เวิร์ดที่ถูกต้อง อะไรทำนองนั้น
ข้อผิดพลาดทางไวยากรณ์มักเกิดจากข้อผิดพลาดลอจิกของคอมไพเลอร์ซึ่งเกิดจากโปรแกรมเมอร์ในระหว่างขั้นตอนการทดสอบ
ความเสียหายของหน่วยความจำก็เป็นปัญหาทั่วไปเช่นกัน โดยเฉพาะใน C
หากคุณไม่ได้เพิ่มหน่วยความจำของคุณหลังจากจัดสรรอย่างถูกต้องแล้ว คุณอาจมีสิ่งต่างๆ
เช่น การอ้างอิงห้อยต่องแต่ง และคุณยังสามารถมีปัญหาเกี่ยวกับหน่วยความจำที่เกี่ยวข้องกับหน่วยความจำที่ไม่ได้ใช้งาน
คุณสามารถมีหน่วยความจำรั่ว
นี่คือตัวอย่างข้อผิดพลาดของหน่วยความจำ
ในรหัสเฉพาะนี้ เรามีหน่วยความจำรั่วจริง ๆ ดังนั้นเราจึงยังไม่ได้พูดถึงพอยน์เตอร์
เรายังไม่ได้พูดถึงการจัดสรรหน่วยความจำแบบไดนามิก
แต่ใน C คุณสามารถจัดสรรหน่วยความจำในขณะที่โปรแกรมของคุณกำลังทำงาน
คุณสามารถใช้ฟังก์ชัน malloc
และตรงนี้เรากำลังทำเครื่องหมาย เรากำลังจัดสรรหน่วยความจำ แต่เราไม่เคยทำให้หน่วยความจำว่าง
ดังนั้นเราจึงสามารถสร้างโค้ดนี้และเรียกใช้ได้ และทุกอย่างก็ดำเนินไปได้ด้วยดี แต่จริงๆ แล้วเราไม่ได้ทำให้ข้อผิดพลาดนี้หายไป
สิ่งที่เราต้องทำเพื่อแก้ไขข้อผิดพลาดของหน่วยความจำนี้คือเราต้องพูดว่าว่างแล้วเราต้องพูดว่าว่างและ
X เพื่อให้ตัวชี้ว่าง
แต่เมื่อใดก็ตามที่คุณจัดสรรหน่วยความจำ คุณไม่ได้ทำให้หน่วยความจำว่าง
นั่นเป็นหน่วยความจำรั่ว
และอีกตัวอย่างหนึ่งก็คือ ถ้าเราไม่จัดสรรหน่วยความจำ ถ้าเราสร้างพอยน์เตอร์แล้วเราพยายามกำหนดมัน
เราจะเกิดความเสียหายของหน่วยความจำเพราะหน่วยความจำนั้นไม่มีการจัดสรรให้กับมัน และเรา
' กำลังพยายามกำหนดค่าให้กับมัน
นั่นเป็นเพียงตัวอย่างเล็ก ๆ น้อย ๆ สำหรับหน่วยความจำ ความเสียหาย ประสิทธิภาพ และความสามารถในการปรับขนาด
นี่อาจเป็นปัญหาที่ฟังก์ชันการทำงานของคุณเป็นไปตามที่เป็นอยู่ และโค้ดของคุณถูกต้องตามไวยากรณ์
แต่ทำงานได้ไม่ค่อยมีประสิทธิภาพ หรือคุณไม่มีฮาร์ดแวร์ที่รองรับ
ดังนั้นหากคุณใช้งานเซิร์ฟเวอร์และไม่มีฮาร์ดแวร์เพียงพอที่จะรองรับคำขอทั้งหมด
เซิร์ฟเวอร์จะทำงานช้ามาก
หรือถ้าคุณเขียนโปรแกรมให้ทำงานกับผู้ใช้ 10 คน แต่เมื่อมีผู้ใช้จำนวนมาก
อาจจะไม่เร็วเท่าเพราะฐานข้อมูลล่มหรือกรณีใดก็ตาม
รหัสใช้งานได้ แต่มันไม่ได้ออกแบบมาอย่างถูกต้องเพื่อรองรับผู้ใช้จำนวนมากหรือจำนวนมากหรืออะไรก็ตาม
ขาดความสามัคคี
นี่อาจเป็นปัญหาในโค้ดของคุณที่ลดคุณภาพเนื่องจากโค้ดของคุณทำงานมากเกินไปหรือฟังก์ชันทำงานมากเกินไป
ไม่ใช่การโฟกัสเพียงจุดเดียวหรือแม้แต่แอปพลิเคชันที่มีฟังก์ชันการทำงานมากเกินไป
มีคุณลักษณะที่ไม่เคยใช้งาน ดังนั้นสิ่งนี้อาจต้องมีการออกแบบใหม่
ต่อไปนี้คือตัวอย่างของโปรแกรมที่จะไม่ถูกทำให้เป็นโมดูล ซึ่งไม่เชื่อมโยงกัน
คุณมีฟังก์ชันใหญ่อย่างหนึ่งที่ทำสิ่งต่างๆ มากเกินไป โค้ดหลายร้อยบรรทัด โค้ดหลายพันบรรทัด
คุณต้องการแบ่งฟังก์ชันออกเป็นฟังก์ชันตัวช่วย แยกโมดูล
ทำให้โปรแกรมของคุณมีความเหนียวแน่นและบำรุงรักษาได้ง่ายขึ้น
ดังนั้น แทนที่จะมีวิธีหลักแบบใหญ่ๆ ที่ทำการเริ่มต้นการอ่านอินพุต ค้นหาบางส่วน
หาผลต่าง ค้นหาผลคูณ หาผลหาร คุณสามารถสร้างโค้ดทั้งหมดนี้และวางไว้ในโมดูลตัวช่วย
และแยกโค้ด และการแยกสามารถช่วยค้นหาได้ และแก้ไขจุดบกพร่องของคุณได้ง่ายขึ้น
ความเหนียวแน่นเป็นสิ่งสำคัญเสมอใน C และมักจะแก้ไขได้เมื่อคุณมีความเหนียวแน่นสูงโดยการจัดเตรียมวิธีการช่วยเหลือ
ข้อต่อแน่น.
สิ่งนี้เกี่ยวข้องกับคุณภาพของโค้ดด้วย
นี่คือที่ที่คุณมีการพึ่งพาจำนวนมาก
การมีเพศสัมพันธ์แตกต่างจากการทำงานร่วมกัน
การทำงานร่วมกันคือจุดสนใจเดียวของคุณ
การมีเพศสัมพันธ์เป็นที่ที่คุณมีการพึ่งพาระหว่างฟังก์ชันหรือระหว่างวัตถุ
เราพูดถึงการมีเพศสัมพันธ์ เราพูดถึงตัวแปรทั่วโลก
หากมีการใช้ตัวแปรตัวแปรส่วนกลางในฟังก์ชันต่างๆ จำนวนมาก อาจทำให้เกิดการพึ่งพาระหว่างฟังก์ชันเหล่านั้นได้
ดังนั้นสิ่งที่คุณต้องการพยายามเมื่อคุณเขียนโค้ดและคุณกำลังเขียนโค้ดคุณภาพสูงก็คือ คุณต้องการให้มีการทำงานร่วมกันที่สูงมากและการมีเพศสัมพันธ์ที่ต่ำมาก
กระบวนการดีบัก
สิ่งแรกที่คุณต้องทำก่อนที่คุณจะสามารถค้นหาและแก้ไขข้อผิดพลาดใดๆ ได้ คุณต้องเข้าใจปัญหา
สิ่งนี้เกี่ยวข้องกับการไม่เพียงแค่ดำดิ่งลงไปและเริ่มดูโค้ด นั่งลงกับผู้ทดสอบ ทำความเข้าใจข้อกำหนด
ทำความเข้าใจกับสิ่งที่เกิดขึ้น
เพราะถ้าคุณไม่เข้าใจสิ่งที่เกิดขึ้น คุณก็จะไม่สามารถ
คุณไม่ควรพยายามแก้ไขด้วยซ้ำ
เมื่อคุณเข้าใจจุดบกพร่องแล้ว ให้ลองทำซ้ำเนื่องจากการทำซ้ำจุดบกพร่องสามารถช่วยให้คุณรวบรวมข้อมูลเพิ่มเติมได้
ไม่สามารถทำซ้ำจุดบกพร่องได้เสมอไป เนื่องจากอาจเกิดขึ้นได้ในสถานการณ์ที่หายากจริงๆ
ตัวอย่างเช่น ข้อบกพร่องที่มีสภาพการแข่งขันหรือแม้แต่ความเสียหายของหน่วยความจำอาจเกิดขึ้นเฉพาะในกรณีการใช้งานที่เฉพาะเจาะจงเท่านั้น
และอาจเป็นปัญหาที่เกิดขึ้นเป็นระยะๆ
และเป็นเช่นนั้นหรือไม่?
และคุณไม่สามารถทำซ้ำได้
การแก้ไขจุดบกพร่องจะยากขึ้นเรื่อยๆ
หากคุณสามารถทำซ้ำได้ โดยปกติแล้ว คุณสามารถรวบรวมข้อมูลได้เพียงพอเพื่อแก้ไข
ปัญหาส่วนใหญ่แก้ไขได้
นอกจากนี้ คุณยังอาจมีปัญหาที่ไม่สามารถสร้างปัญหาขึ้นมาใหม่ได้ หากคุณอยู่ในสภาพแวดล้อมแบบมัลติเธรด
กระบวนการแบบขนาน หรือปัญหาเกี่ยวกับเธรด
สิ่งเหล่านี้ยังแก้ไขจุดบกพร่องได้ยากมาก แต่ให้พยายามสร้างมันขึ้นมาใหม่เมื่อคุณเข้าใจแล้วว่าปัญหาคืออะไรในแง่ของการที่คุณจะสามารถเข้าใจได้เมื่อคุณสร้างมันขึ้นมาใหม่ได้
หากคุณไม่เข้าใจ คุณต้องการลองใช้วิธีการแบ่งแยกและพิชิต
คุณต้องการพยายามแยกจุดบกพร่อง ลดความซับซ้อนของปัญหา เนื่องจากความสามารถในการลดขนาดจะทำให้คุณได้ข้อมูลกลับคืนมา
แต่อาจไม่จำเป็นต้องบอกคุณว่าส่วนใดของจุดบกพร่องอยู่ในโค้ด
ดังนั้น สิ่งที่คุณสามารถทำได้เพื่อลดความซับซ้อนของปัญหาคือลบส่วนของกรณีทดสอบต้นฉบับออก เพื่อไม่ให้คุณทดสอบมากเกินไป
คุณสามารถแยกปัญหาให้เล็กลงได้โดยการพูดว่า โอ้ มันเกิดขึ้นเฉพาะในสถานการณ์เฉพาะนี้เท่านั้น
คุณยังสามารถแสดงความคิดเห็นรหัส
เราพูดถึงฟังก์ชั่นที่มีแค่โครงร่างและไม่มีการนำไปใช้งาน
บางครั้งก็ใช้ในการทดสอบเพื่อให้สามารถจำกัดปัญหาที่ตั้งไว้
นอกจากนี้ หากคุณแสดงความเห็นเกี่ยวกับโค้ด คุณจะมีโค้ดน้อยลงที่จุดบกพร่องสามารถเกิดขึ้นได้จริง
ดังนั้น เมื่อคุณแสดงความคิดเห็นในโค้ดหรือสำรองการเปลี่ยนแปลง จุดบกพร่องอาจหายไปและหากจุดบกพร่องหายไป
นั่นจะบอกคุณว่าโค้ดที่คุณแสดงความคิดเห็นอาจเป็นสาเหตุ
สิ่งที่คุณต้องการทำคือเปลี่ยนโปรแกรมขนาดใหญ่ให้เป็นโปรแกรมขนาดเล็กจำนวนมาก ไม่ว่าจะผ่านการทดสอบหรือแสดงความคิดเห็น
เทคนิคทั่วไปอีกประการหนึ่งคือการทดสอบหน่วยรอบรหัสของคุณ
หากการทดสอบหน่วยล้มเหลว นั่นสามารถบอกคุณได้อย่างแน่ชัดว่าตรรกะหรือปัญหาอาจอยู่ที่ใดในโค้ดของคุณ
เมื่อคุณแยกจุดบกพร่องแล้ว คุณและคนเหล่านั้นจะช่วยคุณค้นหาต้นตอของปัญหาในโค้ด ซึ่งเป็นโค้ดเฉพาะที่ทำให้เกิดปัญหา
บางครั้งการดำเนินการนี้จะใช้เครื่องมือแก้ไขจุดบกพร่อง เช่น ดีบักเกอร์
เราจะพูดถึงดีบักเกอร์แบบเฉพาะเจาะจง แต่โดยทั่วไปแล้วขึ้นอยู่กับการพัฒนาแบบบูรณาการของ
IDE ที่คุณใช้ มีดีบักเกอร์ที่มาพร้อมกับ IDE
นอกจากนี้ยังมีตัวดีบั๊กที่สามารถลงจอดแบบสแตนด์อโลนได้
ดีบักเกอร์สำคัญที่เราจะใช้สำหรับการเขียนโปรแกรม C เรียกว่า GDB
มันคือดีบักเกอร์ GNU ดังนั้นมันจึงเป็นเครื่องมือที่ดีที่จริง ๆ แล้วเป็นเครื่องมือกราฟิกที่คุณสามารถหยุดการทำงานของโปรแกรมและเพิ่มเบรกพอยต์ได้
จากนั้นเมื่อคุณหยุดการดำเนินการ คุณสามารถไปทีละบรรทัดในโค้ดของคุณและดูที่ค่าของตัวแปร
คุณจึงเห็นได้อย่างชัดเจนว่าเกิดอะไรขึ้นในรหัสของคุณในขณะที่กำลังทำงาน
เป็นเครื่องมือล้ำค่า
มันมีประโยชน์มาก
เราจะเรียกใช้ผ่านดีบักเกอร์
ฉันจะแสดงวิธีเพิ่มเบรกพอยต์
ฉันจะแสดงวิธีตั้งค่านาฬิกาเพื่อให้คุณดูตัวแปรเมื่อตัวแปรเปลี่ยนแปลง จากนั้นจึงทำตามขั้นตอนในโค้ด
หลังจากที่คุณระบุต้นตอของปัญหาได้แล้ว คุณจะต้องแก้ไขปัญหานั้น
สิ่งนี้ต้องใช้ประสบการณ์และการฝึกฝนอย่างมาก
เพียงเพราะคุณพบต้นตอของปัญหา คุณยังอาจไม่สามารถแก้ไขได้ตามประสบการณ์ของคุณ
ซึ่งบางครั้งรวมถึงการออกแบบใหม่หรือการปรับโครงสร้างของโค้ดอื่นๆ โดยเฉพาะอย่างยิ่งกับปัญหาด้านความสามารถในการปรับขนาดหรือปัญหาด้านประสิทธิภาพ
คุณอาจต้องออกแบบใหม่เพื่อให้ซอฟต์แวร์ของคุณสามารถปรับขนาดได้มากขึ้น
ดังนั้นการค้นหาปัญหาจึงไม่ใช่เรื่องง่ายเสมอไป
ปัญหาในบางครั้ง โดยเฉพาะอย่างยิ่งปัญหาที่ยากยิ่งกว่า เช่น การทำเธรดหรือการประมวลผลแบบขนาน
ปัญหาเหล่านี้แก้ไขได้ยากยิ่งกว่า
แต่เมื่อคุณเขียนโค้ดมากขึ้นเรื่อยๆ สิ่งนี้จะง่ายขึ้น
และสุดท้ายคุณต้องทดสอบอย่างบ้าคลั่ง
ทดสอบขอบเขตที่แตกต่างกันเสมอ
กรณีที่ดี กรณีที่ไม่ดีระหว่างกรณี เพื่อยืนยันว่าคุณได้แก้ไขปัญหาแล้ว
เทคนิคและเครื่องมือบางอย่างที่มีอยู่
เครื่องมือหนึ่งที่ใช้กันทั่วไปและใช้กันมากคือการใช้คำสั่งพิมพ์
คุณสามารถใช้คำสั่งการพิมพ์เพื่อติดตามรหัสของคุณโดยทั่วไป
ดังนั้นในภาษา C คุณสามารถใช้คำสั่ง print F และคุณสามารถวางไว้หลายบรรทัดในโค้ดของคุณเพื่อระบุว่าคุณอยู่ที่ไหน
สิ่งนี้มีประโยชน์เช่นกัน มีประโยชน์มากเมื่อโปรแกรมของคุณหยุดทำงาน
สามารถช่วยระบุตำแหน่งที่ขัดข้องได้
ขณะที่คุณกำลังเพิ่มคำสั่งการพิมพ์เหล่านี้ที่ติดตามผ่านโค้ดของคุณ คุณสามารถเพิ่มเอาต์พุตในคำสั่งการพิมพ์เพื่อดูค่าของตัวแปรได้
เนื่องจากค่าของตัวแปรอาจส่งผลต่อสถานะและอาจทำให้เกิดปัญหาด้านลอจิก
ดังนั้นการเพิ่มคำสั่งการพิมพ์จึงมีประโยชน์มาก
สามารถแสดงขั้นตอนการดำเนินการและช่วยแยกข้อผิดพลาดได้
ดีบักเกอร์อย่างที่ฉันพูดถึงใน GDB ซึ่งสามารถตรวจสอบการทำงานของโปรแกรมได้
คุณสามารถหยุดมัน คุณสามารถรันทีละบรรทัด รีสตาร์ท ตั้งจุดพัก ดูตัวแปร และหน่วยความจำ
มีประโยชน์มากเมื่อพยายามวิเคราะห์ว่าปัญหาอยู่ที่ใด
ไฟล์บันทึก
ไฟล์บันทึกยังมีประโยชน์มาก โดยเฉพาะอย่างยิ่งสำหรับข้อบกพร่องที่ไม่สามารถสร้างใหม่ได้
คุณสามารถวิเคราะห์ได้ในภายหลังเพื่อดูว่าเกิดอะไรขึ้นเมื่อเกิดข้อบกพร่อง
ซึ่งหมายความว่าคุณต้องจัดเตรียมคำสั่งการบันทึกที่ดีในรหัสของคุณเพื่อให้สิ่งนี้มีประโยชน์
ดังนั้น คุณสามารถสร้างไฟล์บันทึกของคุณเอง แล้วเขียนลงในบันทึกนั้นขณะที่โปรแกรมกำลังทำงาน เพื่อที่ว่าหากคุณมีข้อผิดพลาด
คุณสามารถส่งบันทึกเหล่านั้นไปยังนักพัฒนาได้
เราใช้สิ่งนี้ค่อนข้างน้อยที่ Xerox เพราะเมื่อเราพบปัญหา เราไม่สามารถทำซ้ำได้เสมอ ไม่เช่นนั้นอาจพบได้ในภาคสนาม
เราจำเป็นต้องสามารถเข้าถึงบันทึกเหล่านั้นเพื่อดูว่าเกิดอะไรขึ้นเมื่อจุดบกพร่องนั้นเกิดขึ้น
ซอฟต์แวร์ตรวจสอบ
มีซอฟต์แวร์ที่สามารถตรวจสอบและวิเคราะห์รันไทม์ของการใช้หน่วยความจำ ภัยคุกคามการรับส่งข้อมูลเครือข่าย
และข้อมูลวัตถุ
สิ่งนี้สามารถบอกคุณได้ว่าบางทีคุณอาจจัดสรรหน่วยความจำมากเกินไปและไม่ลบทิ้ง
หากคุณมีเครื่องมือสำหรับการรับส่งข้อมูลเครือข่ายการใช้หน่วยความจำที่สามารถบอกคุณได้ว่าคุณกำลังส่งแพ็กเก็ตมากเกินไปหรือไม่
หรือซอฟต์แวร์ของคุณปรับขนาดได้หรือไม่ หากคุณมีปริมาณการใช้เครือข่ายเพิ่มขึ้นและคุณเห็นว่าการตอบสนองของคุณ
เวลากำลังเสื่อมโทรม
คุณยังสามารถตรวจสอบข้อมูลเธรดและออบเจกต์สำหรับการประมวลผลแบบขนานเพื่อดูว่าเกิดอะไรขึ้นในบางเธรดและสิ่งที่เกิดขึ้นในอีกเธรดหนึ่ง
ซึ่งจะช่วยคุณวินิจฉัยปัญหาประเภทเธรด
เครื่องมือดีบั๊กทั่วไปอื่นๆ ที่คุณสามารถใช้เพื่อค้นหาและแก้ไขข้อผิดพลาดของคุณได้
คุณสามารถใช้การจัดการข้อยกเว้น
ภาษาการเขียนโปรแกรมจำนวนมากมีการจัดการข้อยกเว้น
น่าเสียดายที่ C ไม่มีตัวจัดการข้อยกเว้นที่จะป้องกันการหยุดทำงานและทำหลายสิ่งหลายอย่างในขณะรันไทม์
มันใช้ไม่ได้กับการมองเห็น แต่ก็ยังเป็นสิ่งที่ดีที่จะเข้าใจ
บล็อก Trycatch อะไรทำนองนั้น
เครื่องวิเคราะห์แบบสถิต
มีเครื่องวิเคราะห์แบบสถิตหลายตัวสำหรับเครื่องวิเคราะห์แบบสถิต C
วิเคราะห์ซอร์สโค้ดโดยไม่ต้องเรียกใช้จริง
การรันโปรแกรมไม่จำเป็นต้องรัน
มันไปทีละบรรทัดและดูซอร์สโค้ด
และขณะที่กำลังแยกวิเคราะห์ซอร์สโค้ด ก็จะค้นหาปัญหาที่ทราบ
ดังนั้นจึงสามารถตรวจสอบความหมายได้
ก็สามารถทำให้แน่ใจได้ว่า
แค่นั้นแหละ.
คุณไม่มีตัวแปรที่ไม่ได้กำหนดค่าเริ่มต้น หากคุณกำลังจัดสรรหน่วยความจำใหม่ ให้ลบทิ้ง
หากคุณมีรหัสที่ตายแล้วซึ่งรหัสไม่ได้ถูกดำเนินการจริง คุณสามารถลบรหัสนั้นได้
นอกจากนี้ยังวิเคราะห์สิ่งต่างๆ เช่น สภาพการแข่งขันและการหยุดชะงัก
เราใช้เครื่องวิเคราะห์แบบคงที่สองสามเครื่องในที่ทำงานของฉัน
เรามีเครื่องมือที่เรียกว่า Coverity ซึ่งค่อนข้างเป็นที่นิยม และมีเครื่องมือโซนาร์โค้ดที่เราใช้เช่นกัน และเราจะเรียกใช้สิ่งนี้บนพื้นฐานทั้งหมดของเรา
ชุดแหล่งที่มาทั้งหมดของเรา
และเมื่อใดก็ตามที่เราแนะนำไฟล์ใหม่และโค้ดใหม่ เครื่องมือนั้นจะทำงานบนโค้ดนั้น และจะสามารถระบุปัญหาที่เกิดขึ้นกับโค้ดได้ทันที
ตราบใดที่ตัวแปรที่ไม่ได้เตรียมใช้งาน หน่วยความจำรั่ว และอื่นๆ
มันไม่ได้วิเคราะห์ไวยากรณ์
นั่นคือสิ่งที่คอมไพเลอร์มีไว้
นอกจากนี้ยังมีชุดทดสอบจำนวนหนึ่งที่เรียกใช้ชุดการทดสอบระบบแบบครอบคลุมตั้งแต่ต้นจนจบ ซึ่งคุณสามารถรันบนซอฟต์แวร์ของคุณได้
การทดสอบมีความสำคัญเสมอ แต่ถ้าคุณสามารถทำให้การทดสอบเป็นแบบอัตโนมัติด้วยวิธีใดวิธีหนึ่งในการเรียกใช้การทดสอบบางอย่างทุกครั้งที่คุณสร้างงานสร้างใหม่
ซึ่งจะมีประโยชน์มากและสิ่งนี้สามารถป้องกันข้อผิดพลาดได้จริง แต่ก็ช่วยวินิจฉัยข้อผิดพลาดได้เช่นกัน
การดีบักโปรแกรมหลังจากที่มันพัง
เราจะพูดถึงสิ่งที่เรียกว่า call stack
นี่เป็นกลไกที่มีประโยชน์มากในการดู โดยเฉพาะอย่างยิ่งในภาษาอย่างเช่น C ที่คุณมีข้อขัดข้องและข้อมูลเดียวที่คุณได้รับคือข้อผิดพลาดของการแบ่งกลุ่ม
เมื่อคุณเกิดข้อขัดข้องนั้น จะเกิดอะไรขึ้นบ่อยครั้งขึ้นอยู่กับว่ามันเกิดข้อขัดข้องอย่างไร ไฟล์หลักจะถูกสร้างขึ้นและคุณสามารถวิเคราะห์ไฟล์หลักเพื่อดูที่
call stack เพื่อดูว่าโปรแกรมนั้นหยุดทำงานตรงไหน
มันจะบอกคุณบรรทัดของรหัสที่โปรแกรมตาย
ดังนั้น เราจะมาเรียนรู้เกี่ยวกับ call stack
และเท่าที่วิเคราะห์ไฟล์หลัก นั่นเป็นเทคนิคขั้นสูงมากกว่า
แต่ใน C สามารถสร้างไฟล์หลักและคุณสามารถวิเคราะห์ได้
นั่นเป็นเทคนิคขั้นสูงเล็กน้อย แต่นั่นเป็นอีกวิธีหนึ่งที่คุณสามารถทำการดีบักซอฟต์แวร์ของคุณได้
สิ่งที่เกี่ยวกับการป้องกันข้อผิดพลาด?
เราทราบดีว่าการแก้ไขจุดบกพร่องคือการค้นหาและแก้ไขข้อผิดพลาด แต่ถ้าคุณสามารถป้องกันข้อผิดพลาดได้ นั่นจะดียิ่งกว่า
วิธีหนึ่งที่คุณสามารถป้องกันข้อผิดพลาดได้คือคุณสามารถเขียนโค้ดคุณภาพสูงได้
นี่ไม่ใช่จุดสนใจของวิศวกรซอฟต์แวร์จำนวนมาก
วิศวกรซอฟต์แวร์จำนวนมากเขียนโค้ด และตราบใดที่มันใช้งานได้ นั่นคือทั้งหมดที่พวกเขากังวล
หรือตราบใดที่ผลลัพธ์ถูกต้อง พวกเขาก็คิดว่าตัวเองทำสำเร็จแล้ว
แต่มีบางอย่างเช่นโค้ดคุณภาพต่ำและคุณไม่ต้องการเขียนสิ่งนั้น
ฉันได้แสดงให้เห็นบางส่วนในระหว่างการบรรยาย แต่สิ่งต่างๆ เช่น การใช้ชื่อตัวแปรที่สื่อความหมายมีความสำคัญมาก
หรือถ้าคุณเขียนโค้ดที่ไม่มีประสิทธิภาพโดยที่คุณใช้การวนซ้ำ อาจจะมากกว่าที่คุณต้องการ หรือใช้คำสั่ง
if หรือคุณไม่จำเป็นต้องทำเช่นนั้น
สิ่งเหล่านี้ล้วนเป็นรหัสคุณภาพต่ำ
หากคุณมีฟังก์ชันที่ทำสิ่งอื่นอีก 100 รายการและไม่เชื่อมโยงกัน ถ้าคุณมี 5,000 บรรทัดในฟังก์ชัน
ถ้าโค้ดของคุณไม่ได้จัดระเบียบในรูปแบบโมดูลาร์หรือหากคุณมีการพึ่งพาระหว่างฟังก์ชันจำนวนมาก
ทั้งหมดนี้ไม่ดี รหัสคุณภาพและคุณต้องการที่จะพยายามไม่ทำเช่นนี้
คุณต้องการใช้เทคนิคในการจัดระเบียบโปรแกรมของคุณ
ง่ายต่อการบำรุงรักษา มีความเหนียวสูง มีการมีเพศสัมพันธ์ต่ำ และคุณใช้ชื่อตัวแปรที่มีความหมาย
สำคัญมาก
อีกครั้ง มันสำคัญมากเช่นกันเพราะขั้นตอนการบำรุงรักษานั้นแพงมาก
หากคุณเขียนโค้ดคุณภาพต่ำ การดูแลรักษาจะยากขึ้นมาก
การแยกข้อผิดพลาดทำได้ยากขึ้นและเพิ่มคุณสมบัติใหม่ได้ยากขึ้น
ดังนั้นเทคนิคคุณภาพสูงที่ดีของพนักงานเมื่อเขียนโค้ดของคุณ
การทดสอบหน่วย
การทดสอบหน่วยช่วยป้องกันข้อผิดพลาดอย่างมาก
โดยปกติการทดสอบหน่วยจะดำเนินการโดยอัตโนมัติเมื่อคุณรวบรวมการทดสอบหน่วยสามารถช่วยหลีกเลี่ยงการถดถอย
นั่นเป็นหนึ่งในปัจจัยที่สำคัญที่สุด
การถดถอยคือการที่คุณเขียนโค้ดใหม่และคุณแนะนำจุดบกพร่องของบางอย่างที่เคยใช้งานได้
คุณทำลายรหัสเก่า
คุณไม่ต้องการทำอย่างนั้น
หากซอฟต์แวร์บางตัวใช้งานได้และมีสิ่งใหม่ที่คุณทำมันพัง คุณต้องได้รับแจ้งทันทีและการทดสอบหน่วยสามารถช่วยได้เนื่องจากการทดสอบหน่วยจะทำงานบนรหัสเก่านั้นและมันจะพูดว่า
เฮ้ ใช้งานได้แล้ว ตอนนี้มันทำงาน ล้มเหลว
นอกจากนี้ยังสามารถค้นหาข้อผิดพลาดในโค้ดใหม่ก่อนที่จะส่ง เนื่องจากอีกครั้ง ข้อผิดพลาดจะทำงานหลังจากคุณสร้างและจะแจ้งให้คุณทราบทันทีว่ามีบางอย่างผิดปกติ
มีแนวคิดของการพัฒนาแบบทดสอบขับเคลื่อนซึ่งกำลังได้รับความนิยมอย่างมาก
นี่คือที่ที่คุณเขียนการทดสอบก่อน แล้วจึงพัฒนาโค้ดของคุณในภายหลัง
และเป้าหมายที่นี่คือเมื่อคุณเขียนการทดสอบครั้งแรก การทดสอบของคุณล้มเหลว จากนั้นคุณก็เขียนโค้ดเพื่อให้ผ่าน
มีข้อดีมากมายสำหรับ TDD และเป็นวิธีคิดแบบย้อนกลับ
โดยปกติแล้ว เวลาเขียนโค้ด คนทั่วไปจะเขียนโค้ดก่อน แล้วจึงเขียนทดสอบทีหลัง
แต่ด้วย TDD มันให้วิธีคิดที่แตกต่างออกไป ดังนั้นคุณจึงทำงานเป็นชิ้นเล็ก
ๆ และคุณมักจะเขียนโค้ดที่เหนียวแน่นมาก และคุณไม่มีโค้ด ไม่มีการพึ่งพาจำนวนมากเพราะเดา
อะไร?
หากคุณสามารถทดสอบโค้ดได้ แสดงว่าโค้ดไม่มีการพึ่งพามากนัก
หากการทดสอบหน่วยของคุณมีขนาดใหญ่จริงๆ และคุณกำลังล้อเลียนสิ่งที่แตกต่างกันเหล่านี้
ก็มักจะเป็นตัวบ่งชี้ที่สำคัญว่าโค้ดของคุณนั้นขึ้นอยู่กับสิ่งอื่นๆ เป็นอย่างมาก
ดังนั้น เมื่อใช้ TDD มันบังคับให้คุณเขียนโค้ดที่เชื่อมโยงกันอย่างหลวมๆ ซึ่งไม่มีการขึ้นต่อกัน และบังคับให้คุณมีหน้าที่เชื่อมโยงกันอย่างมาก
ข้อดีของ TDD มีมากมาย
คุณยังต้องการจัดทำเอกสารที่ดีและต้องการวางแผนอย่างเหมาะสม
อย่าเพิ่งดำดิ่งลงไปในโค้ดและเริ่มใช้งาน
เขียนการออกแบบของคุณลงบนกระดาษ
ใช้รหัสเทียม
ขวา.
วางแผนรหัสของคุณ
หากคุณวางแผนโค้ดของคุณ คุณเข้าใจข้อกำหนดและคุณมีการออกแบบที่รอบคอบ คุณสามารถป้องกันข้อผิดพลาดมากมาย
และฉันได้พูดถึงสิ่งนี้ตลอดหลักสูตร แต่มันสำคัญมากที่จะต้องมีวิธีการแบ่งและพิชิต
ทำงานในขั้นตอนเล็ก ๆ และทดสอบอย่างต่อเนื่องหลังจากแต่ละขั้นตอน อย่าเขียนโค้ด 1,000 บรรทัดแล้วพูดว่า
โอเค คอมไพล์ และทดสอบ
นั่นไม่ใช่แนวทางที่ดี
หลีกเลี่ยงการเปลี่ยนแปลงมากเกินไปในคราวเดียว
เมื่อทำการเปลี่ยนแปลง ให้ใช้ทีละส่วน เพิ่มการเปลี่ยนแปลงหนึ่งรายการ จากนั้นทดสอบอย่างละเอียดก่อนเริ่มขั้นตอนถัดไป
สิ่งนี้สามารถช่วยลดข้อบกพร่องทุกประเภทและยังจำกัดชุดปัญหาของคุณด้วย
ดังนั้นหากคุณมีบั๊ก คุณจะรู้ได้ทันทีว่ามันอยู่ที่ไหนในโค้ด เพราะคุณเพิ่งคอมไพล์และคุณเพิ่งเพิ่มบรรทัดหรือจำนวนบรรทัดนั้น
อีกครั้ง ฉันไม่สามารถเน้นย้ำถึงความสำคัญของการดีบักการเขียนโค้ดคุณภาพสูง การป้องกันข้อผิดพลาด
เทคนิคการแก้ปัญหาเหล่านี้จะช่วยให้คุณประหยัดเวลาได้มาก และทำให้คุณเป็นโปรแกรมเมอร์ระดับบนของโปรแกรมเมอร์ที่ดียิ่งขึ้น
ดังนั้นในการบรรยายครั้งต่อไป ผมอยากจะพูดถึงข้อผิดพลาดทั่วไปบางประการที่เราเห็นในภาษาการเขียนโปรแกรม
c
นอกจากนี้ ฉันต้องการพูดคุยเกี่ยวกับ call stack เล็กน้อย
ฉันต้องการดูโปรแกรมดีบั๊กที่แนะนำตัวเลือกเมนูและวิธีหยุดและเรียกใช้นาฬิกา
และอื่นๆ
และฉันยังต้องการช่วยระบุข้อผิดพลาดของคอมไพเลอร์ทั่วไปที่คุณเห็นวิธีตีความคอมไพเลอร์ คำเตือนและข้อผิดพลาดของคอมไพเลอร์
หมายความว่าอย่างไรถ้าคอมไพเลอร์พูดแบบนี้?
หมายความว่าอย่างไรหากคอมไพเลอร์ให้คำเตือนนี้แก่คุณ
ขอบคุณ