แบบฝึกหัด - ดีบักด้วย Visual Studio
ถึงเวลาแล้วที่จะนําความรู้การดีบักที่เพิ่งได้รับมาใหม่ของคุณไปสู่การปฏิบัติ เป็นวันแรกของคุณในงานและคุณต้องการใส่ทักษะการดีบัก .NET ของคุณเพื่อทํางานโดยการแก้ไขข้อบกพร่องในผลิตภัณฑ์เรือธงของ บริษัท เครื่องคิดเลข Fibonacci
สร้างโครงการ .NET ตัวอย่างสําหรับการดีบัก
เมื่อต้องการตั้งค่าการดีบัก Visual Studio สําหรับ .NET ก่อนอื่นเราต้องใช้โครงการ .NET Visual Studio มีเทมเพลตเริ่มต้นมากมายที่ทําให้การสร้างโครงการใหม่เป็นเรื่องง่าย
ใน Visual Studio ให้เลือก ไฟล์ >โครงการ>ใหม่
ในกล่องโต้ตอบ สร้าง โครงการใหม่ ให้เลือก แอปคอนโซล และเลือก ถัดไป
ตั้งชื่อโครงการ DotNetDebuggingและเลือกตําแหน่งที่ตั้งที่คุณต้องการบันทึก ปล่อยค่าอื่นๆ ไว้เป็นค่าเริ่มต้น จากนั้นเลือก ถัดไป
เลือก สร้าง บนหน้าจอสุดท้าย
Visual Studio สร้างโครงการคอนโซลสําหรับเราโดยใช้เทมเพลตที่เราเลือก เมื่อโหลดโครงการแล้ว ให้เปิด Program.cs โดยการเลือก
เพิ่มตรรกะโปรแกรม Fibonacci
โครงการปัจจุบันของเราเขียนข้อความ "Hello World" ไปยังคอนโซลซึ่งไม่ได้ให้เราแก้จุดบกพร่องมากนัก แต่เรามาใช้โปรแกรม .NET สั้น ๆ เพื่อคํานวณจํานวนN ของลําดับ Fibonacci
ลําดับ Fibonacci คือชุดของตัวเลขที่เริ่มต้นด้วยตัวเลข 0 และ 1 โดยที่ตัวเลขอื่น ๆ ทั้งหมดต่อไปนี้เป็นผลรวมของตัวเลขสองตัวก่อนหน้า ลําดับจะดําเนินต่อไปดังที่แสดงไว้ที่นี่:
0, 1, 1, 2, 3, 5, 8, 13, 21...
รหัสตัวอย่างต่อไปนี้ประกอบด้วยข้อบกพร่อง ดังนั้นเรามาใช้เครื่องมือการดีบักของ Visual Studio ในการวินิจฉัยและแก้ไขปัญหา
- แทนที่เนื้อหาของ Program.cs ด้วยโค้ดต่อไปนี้:
int result = Fibonacci(5);
Console.WriteLine(result);
static int Fibonacci(int n)
{
Console.WriteLine("The output is: ");
int n1 = 0;
int n2 = 1;
int sum;
for (int i = 2; i < n; i++)
{
sum = n1 + n2;
n1 = n2;
n2 = sum;
}
return n == 0 ? n1 : n2;
}
โน้ต
รหัสนี้มีข้อผิดพลาดที่เราแก้จุดบกพร่องในภายหลังในโมดูลนี้ เราไม่แนะนําให้คุณใช้ในแอปพลิเคชัน Fibonacci ใด ๆ ที่สําคัญต่อภารกิจจนกว่าเราจะแก้ไขบั๊กนั้น
บันทึกไฟล์ด้วย Ctrl + S สําหรับ Windows และ Linux เลือก Cmd+S สําหรับ Mac
มาดูกันว่าโค้ดที่อัปเดตทํางานอย่างไรก่อนที่เราจะแก้จุดบกพร่อง เรียกใช้โปรแกรมโดยการกดปุ่มเริ่มต้นสีเขียวในแถบคําสั่ง Visual Studio
ในตอนท้ายของดีบักคอนโซลเอาต์พุตคุณจะเห็นว่าโปรแกรมเขียน 3 ไปยังคอนโซลแล้วออกจากระบบด้วยรหัส 0 โดยปกติแล้วรหัสออกจากโปรแกรมเป็น 0 แสดงว่าโปรแกรมเรียกใช้และจบการทํางานโดยไม่หยุดทํางาน อย่างไรก็ตาม มีความแตกต่างระหว่างการหยุดทํางานและส่งกลับค่าที่ถูกต้อง
หน้าต่างเทอร์มินัล
ในกรณีนี้ เราขอให้โปรแกรมคํานวณค่าที่ห้าของลําดับ Fibonacci:
0, 1, 1, 2, 3, 5, 8, 13, 21...
ค่าที่ห้าในรายการนี้คือ 5 แต่โปรแกรมของเราส่งกลับค่า 3 ลองใช้ตัวแก้ไขจุดบกพร่องเพื่อวินิจฉัยและแก้ไขข้อผิดพลาดนี้
ใช้จุดสั่งหยุดและการดําเนินการทีละขั้นตอน
เพิ่มจุดสั่งหยุดโดยการคลิกระยะขอบซ้ายที่เส้น 1 บน
int result = Fibonacci(5);เริ่มดีบักอีกครั้ง โปรแกรมเริ่มดําเนินการ การหยุดทํางาน (หยุดการทํางานชั่วคราว) บนบรรทัด 1 เนื่องจากจุดสั่งหยุดที่คุณตั้งค่าไว้ ใช้ตัวควบคุมตัวแก้ไขจุดบกพร่องเพื่อทําให้ฟังก์ชัน
Fibonacci()เป็นขั้น
ตรวจสอบสถานะของตัวแปร
ตอนนี้ลองใช้เวลาสักครู่เพื่อตรวจสอบค่าตัวแปรต่างๆ โดยใช้หน้าต่าง Locals
- ค่าที่แสดงสําหรับพารามิเตอร์
nคืออะไร - ที่จุดเริ่มต้นของการดําเนินการของฟังก์ชัน ค่าสําหรับตัวแปรภายในเครื่อง
n1n2และsumคืออะไร
ถัดไป เราจะก้าวไปสู่การ
forวนรอบโดยใช้ตัวควบคุมตัวแก้ไขจุดบกพร่องของขั้นตอน
ดําเนินการพัฒนาต่อไปจนกว่าจะถึงบรรทัดแรกภายในการ
forวนรอบ บรรทัดที่อ่าน:sum = n1 + n2;
โน้ต
คุณอาจสังเกตเห็นว่าการเลื่อนผ่าน for(...) {} บรรทัดจําเป็นต้องมีหลายขั้นตอนในคําสั่ง สถานการณ์นี้เกิดขึ้นเนื่องจากมีคําสั่ง หลายคําสั่ง บนบรรทัดนี้ เมื่อคุณทําขั้นตอน คุณย้ายไปยังคําสั่งถัดไปในรหัสของคุณ โดยปกติแล้ว จะมีคําสั่งหนึ่งคําสั่งต่อหนึ่งบรรทัด ถ้าไม่เป็นเช่นนั้น คุณจําเป็นต้องมีหลายขั้นตอนเพื่อย้ายไปยังบรรทัดถัดไป
คิดเกี่ยวกับโค้ด
ส่วนสําคัญของการแก้ไขจุดบกพร่องคือการหยุดและใช้การคาดเดาอย่างชาญฉลาดเกี่ยวกับสิ่งที่คุณคิดว่าส่วนหนึ่งของโค้ด (ทั้งฟังก์ชันและบล็อก เช่น ลูป) กําลังพยายามทํา หากคุณไม่แน่ใจ ก็เป็นส่วนหนึ่งของกระบวนการดีบัก แต่การมีส่วนร่วมอย่างแข็งขันในกระบวนการดีบักช่วยให้คุณค้นหาข้อบกพร่องได้อย่างรวดเร็วมาก
ก่อนที่เราจะเจาะลึกเพิ่มเติม มาจําไว้ว่าลําดับ Fibonacci คือชุดของตัวเลขที่เริ่มต้นด้วยตัวเลข 0 และ 1 โดยที่ตัวเลขอื่น ๆ ต่อไปนี้เป็นผลรวมของสองตัวเลขก่อนหน้า
นั่นหมายความว่า:
Fibonacci(0) = 0
Fibonacci(1) = 1
Fibonacci(2) = 1 (0 + 1)
Fibonacci(3) = 2 (1 + 1)
Fibonacci(4) = 3 (1 + 2)
Fibonacci(5) = 5 (2 + 3)
การทําความเข้าใจข้อกําหนดดังกล่าวและดูที่ for รอบนี้ เราสามารถอนุมานได้ว่า:
- รอบจะนับจาก 2 เป็น
n(หมายเลขลําดับ Fibonacci ที่เรากําลังค้นหา) - ถ้า
nน้อยกว่า 2 รอบจะไม่ทํางาน คําสั่งreturnที่ส่วนท้ายของฟังก์ชันจะแสดงค่า 0 ถ้าnเป็น 0 และ 1 ถ้าnเป็น 1 หรือ 2 ค่าเหล่านี้เป็นค่าศูนย์ ค่าแรก และค่าที่สองในชุด Fibonacci ตามข้อกําหนด - กรณีที่น่าสนใจกว่าคือเมื่อ
nมากกว่า 2 ในกรณีดังกล่าว ค่าปัจจุบันจะถูกกําหนดเป็นผลรวมของสองค่าก่อนหน้า ดังนั้นสําหรับรอบนี้n1และn2คือสองค่าก่อนหน้า และsumคือค่าสําหรับการทําซ้ําปัจจุบัน เนื่องจากตรรกะนี้ แต่ละครั้งที่เราหาผลรวมของสองค่าก่อนหน้านี้ และตั้งค่าเป็นsumเราอัปเดตค่า และn1ของเราn2
โอเค เราไม่จําเป็นต้องคิดมากเกินไป เราสามารถเอนตัวแก้ไขจุดบกพร่องของเราได้เล็กน้อย แต่ก็คุ้มค่าที่จะคิดเกี่ยวกับรหัสเพื่อดูว่ามันทําสิ่งที่เราคาดหวังและได้รับทราบข้อมูลเพิ่มเติมหรือไม่เมื่อไม่เป็นเช่นนั้น
ค้นหาบั๊กที่มีจุดสั่งหยุด
การทําตามโค้ดของคุณจะมีประโยชน์แต่น่าเบื่อ โดยเฉพาะอย่างยิ่งเมื่อคุณกําลังทํางานกับรอบหรือโค้ดอื่น ๆ ที่เรียกว่าซ้ํา ๆ แทนที่จะผ่านการวนรอบไปมาซ้ําแล้วซ้ําอีก เราสามารถตั้งค่าจุดสั่งหยุดใหม่บนบรรทัดแรกของรอบได้
สิ่งสําคัญคือเป็นกลยุทธ์เกี่ยวกับจุดสั่งหยุดของเรา เราสนใจโดยเฉพาะอย่างยิ่งในค่าของ sumเนื่องจากแสดงถึงค่า Fibonacci สูงสุดในปัจจุบัน ดังนั้น เรามาใส่จุดสั่งหยุดของเราบนบรรทัด หลังจากsum ที่มีการตั้งค่า
เพิ่มจุดสั่งหยุดที่สองบนบรรทัด 14
โน้ต
หากคุณสังเกตเห็นว่าคุณยังคงเรียกใช้โค้ดอยู่ และจากนั้นต่อบรรทัดหนึ่งหรือสองบรรทัด คุณสามารถอัปเดตจุดสั่งหยุดของคุณเป็นบรรทัดที่มีประสิทธิภาพมากขึ้นได้อย่างง่ายดาย
ตอนนี้เรามีจุดสั่งหยุดที่ดีในรอบ เลือก ดําเนินการต่อ ในตัวควบคุมตัวแก้ไขจุดบกพร่องเพื่อเลื่อนออกไปจนกว่าจะถึงจุดสั่งหยุด เมื่อดูตัวแปรภายในเครื่องของเรา เราเห็นบรรทัดต่อไปนี้:
n [int]: 5 n1 [int]: 0 n2 [int]: 1 sum [int]: 1 i [int]: 2บรรทัดเหล่านี้ดูเหมือนถูกต้อง ครั้งแรกที่ผ่านการวนรอบ
sumของสองค่าก่อนหน้าคือ 1 แทนที่จะผ่านบรรทัดต่อบรรทัด เราสามารถใช้ประโยชน์จากจุดสั่งหยุดของเราเพื่อข้ามไปยังครั้งถัดไปผ่านรอบเลือก ดําเนินการต่อ เพื่อดําเนินต่อโฟลว์โปรแกรมจนกว่าจะถึงจุดสั่งหยุดถัดไป ซึ่งจะผ่านลูปถัดไป
โน้ต
อย่ากังวลมากเกินไปเกี่ยวกับการข้ามจุดบกพร่องเมื่อคุณใช้ ดําเนินการต่อ คุณควรคาดหวังว่าคุณอาจดีบักผ่านรหัสหลายครั้งเพื่อค้นหาปัญหา บ่อยครั้งที่มักจะทํางานได้เร็วกว่าการเรียกใช้เพียงไม่กี่ครั้งเมื่อเทียบกับการระมัดระวังมากเกินไปเมื่อคุณก้าวผ่าน
ในครั้งนี้ เราเห็นค่าต่อไปนี้:
n [int]: 5 n1 [int]: 1 n2 [int]: 1 sum [int]: 2 i [int]: 3ค่าเหล่านี้ยังสมเหตุสมผลหรือไม่ ดูเหมือนว่าพวกเขาจะทําเช่นนั้น สําหรับหมายเลข Fibonacci ที่สาม เราคาดว่าจะเห็น
sumของเราเท่ากับ 2 และมันเป็นเลือก ดําเนินการต่อ เพื่อวนรอบอีกครั้ง
n [int]: 5 n1 [int]: 1 n2 [int]: 2 sum [int]: 3 i [int]: 4ผลลัพธ์ถูกต้อง ค่าที่สี่ในชุดข้อมูลคาดว่าจะเป็น 3
ในตอนนี้คุณอาจเริ่มสงสัยว่ารหัสถูกต้องหรือไม่และคุณจินตนาการถึงข้อผิดพลาดหรือไม่! ลองเก็บไว้เป็นครั้งสุดท้ายผ่านรอบ เลือก ดําเนินการต่อ อีกครั้ง
โปรแกรมทํางานเสร็จแล้วและเอาต์พุตคือ 3! ผลลัพธ์ของเราไม่ถูกต้อง
ในตอนนี้เราทราบว่ารหัสทํางานผ่านการวนรอบอย่างถูกต้องจนกว่า
iเท่ากับ 4 แต่จากนั้นจะออกจากระบบก่อนคํานวณค่าสุดท้าย เราจํากัดให้แคบลงว่าจุดบกพร่องอยู่ที่ไหนลองตั้งค่าจุดสั่งหยุดเพิ่มเติมหนึ่งจุดบนบรรทัด 18 ซึ่งอ่าน:
return n == 0 ? n1 : n2;จุดสั่งหยุดนี้ช่วยให้เราสามารถตรวจสอบสถานะของโปรแกรมก่อนที่ฟังก์ชันจะจบการทํางาน เราได้เรียนรู้ทุกอย่างที่เราสามารถคาดหวังได้จากจุดสั่งหยุดก่อนหน้านี้ของเราในบรรทัดที่ 1 และ 13 เพื่อให้เราสามารถล้างจุดเหล่านั้นได้
ลบจุดสั่งหยุดก่อนหน้าของเราในบรรทัด 1 และ 13 เลือกจุดสั่งหยุดในระยะขอบถัดจากหมายเลขบรรทัด หรือล้างกล่องกาเครื่องหมายจุดสั่งหยุดสําหรับบรรทัด 1 และ 13 ในบานหน้าต่างจุดสั่งหยุดในบานหน้าต่างจุดสั่งหยุดที่ด้านล่างซ้าย
ตอนนี้เราเข้าใจมากขึ้นว่าสิ่งที่เกิดขึ้นและตั้งค่าจุดสั่งหยุดที่ออกแบบมาเพื่อจับโปรแกรมของเราในการทําหน้าที่ของ misbehaving ตอนนี้เราควรจะสามารถจับบักนี้!
เริ่มต้นตัวแก้ไขจุดบกพร่องครั้งที่แล้ว
n [int]: 5 n1 [int]: 2 n2 [int]: 3 sum [int]: 3เราขอ Fibonacci(5) โดยเฉพาะและเรามี Fibonacci(4) ซึ่งไม่ถูกต้อง ฟังก์ชันนี้ส่งกลับ
n2และการทําซ้ํารอบแต่ละครั้งจะคํานวณค่าsumและตั้งค่าn2เท่ากับsumจากข้อมูลนี้และการเรียกใช้ดีบักก่อนหน้านี้ของเราเราจะเห็นว่าการวนรอบถูกออกเมื่อ
iเป็น 4 ไม่ใช่ 5มาดูคําสั่งรอบของเรา
forให้ละเอียดขึ้นอีกเล็กน้อยfor (int i = 2; i < n; i++)ตรรกะนี้ทําให้โปรแกรมออกจากระบบทันทีที่ด้านบนสุดของรอบ สําหรับ จะเห็น
iเท่ากับnซึ่งหมายความว่ารหัสรอบไม่สามารถเรียกใช้ได้สําหรับกรณีที่iเท่ากับnดูเหมือนว่าสิ่งที่เราต้องการเรียกใช้จนกว่าจะi <= nแทน:for (int i = 2; i <= n; i++)ดังนั้นด้วยการเปลี่ยนแปลงโปรแกรมที่อัปเดตแล้วของคุณควรมีลักษณะเหมือนตัวอย่างนี้:
int result = Fibonacci(5); Console.WriteLine(result); static int Fibonacci(int n) { Console.WriteLine("The output is: "); int n1 = 0; int n2 = 1; int sum; for (int i = 2; i <= n; i++) { sum = n1 + n2; n1 = n2; n2 = sum; } return n == 0 ? n1 : n2; }หยุดเซสชันการดีบักถ้าคุณยังไม่ได้ทํา
ทําการเปลี่ยนแปลงก่อนหน้านี้ไปที่บรรทัด 11 และปล่อยจุดสั่งหยุดของคุณบนบรรทัด 18
เริ่มโปรแกรมดีบักเกอร์ใหม่ ครั้งนี้ เมื่อเรากดจุดสั่งหยุดบนบรรทัด 18 เราจะเห็นค่าต่อไปนี้:
n [int]: 5 n1 [int]: 3 n2 [int]: 5 sum [int]: 5หวัดดี! มันเหมือนเราได้มันมาแล้ว! ทํางานได้ยอดเยี่ยมคุณบันทึกวันสําหรับ Fibonacci, Inc.!
เลือก ดําเนินการต่อ เพียงเพื่อให้แน่ใจว่าโปรแกรมส่งกลับค่าที่ถูกต้อง
5 The program '[105260] DotNetDebugging.dll' has exited with code 0 (0x0).และแสดงผลลัพธ์ที่ถูกต้อง
คุณทําได้แล้ว! คุณได้ดีบักโค้ดที่คุณไม่ได้เขียนโดยใช้ตัวดีบักเกอร์ .NET ใน Visual Studio
ในหน่วยถัดไป คุณจะได้เรียนรู้วิธีการทําให้โค้ดที่คุณเขียนง่ายขึ้นเพื่อดีบักโดยใช้คุณลักษณะการบันทึกและการติดตามที่มีอยู่ภายใน .NET