ดีบักเกอร์คืออะไรและจะช่วยฉันวินิจฉัยปัญหาได้อย่างไร

Aug 19 2014

นี่เป็นคำถามที่มีวัตถุประสงค์ทั่วไปเพื่อช่วยเหลือโปรแกรมเมอร์มือใหม่ที่มีปัญหากับโปรแกรม แต่ไม่ทราบวิธีใช้ดีบักเกอร์เพื่อวินิจฉัยสาเหตุของปัญหา

คำถามนี้ครอบคลุมคำถามที่เฉพาะเจาะจงมากขึ้นสามประเภท:

  • เมื่อฉันรันโปรแกรมของฉันมันไม่ได้สร้างผลลัพธ์ที่ฉันคาดหวังสำหรับอินพุตที่ฉันให้ไว้
  • เมื่อฉันรันโปรแกรมมันขัดข้องและส่งสแต็กเทรซ ฉันได้ตรวจสอบการติดตามสแต็กแล้ว แต่ฉันยังไม่ทราบสาเหตุของปัญหาเนื่องจากการติดตามสแต็กให้ข้อมูลไม่เพียงพอ
  • เมื่อฉันเรียกใช้โปรแกรมโปรแกรมขัดข้องเนื่องจากข้อผิดพลาดในการแบ่งส่วน (SEGV)

คำตอบ

68 Raedwald Aug 19 2014 at 20:49

ดีบักเกอร์คือโปรแกรมที่สามารถตรวจสอบสถานะของโปรแกรมของคุณในขณะที่โปรแกรมของคุณกำลังทำงานอยู่ วิธีการทางเทคนิคที่ใช้ในการทำสิ่งนี้ไม่สำคัญสำหรับการทำความเข้าใจพื้นฐานของวิธีใช้ดีบักเกอร์ คุณสามารถใช้ดีบักเกอร์เพื่อหยุดการทำงานของโปรแกรมของคุณเมื่อถึงตำแหน่งใดตำแหน่งหนึ่งในโค้ดของคุณจากนั้นตรวจสอบค่าของตัวแปรในโปรแกรม คุณสามารถใช้ดีบักเกอร์เพื่อเรียกใช้โปรแกรมของคุณอย่างช้าๆทีละบรรทัดของโค้ด (เรียกว่าsingle step ) ในขณะที่คุณตรวจสอบค่าของตัวแปร

การใช้ดีบักเกอร์เป็นทักษะพื้นฐานที่คาดหวัง

ดีบักเกอร์เป็นเครื่องมือที่มีประสิทธิภาพมากในการช่วยวินิจฉัยปัญหาเกี่ยวกับโปรแกรม และดีบักเกอร์พร้อมใช้งานสำหรับภาษาโปรแกรมที่ใช้ได้จริงทั้งหมด ดังนั้นความสามารถในการใช้ดีบักเกอร์จึงถือเป็นทักษะพื้นฐานของโปรแกรมเมอร์มืออาชีพหรือผู้ที่กระตือรือร้น และการใช้ดีบักเกอร์ด้วยตัวเอง ถือเป็นงานพื้นฐานที่คุณควรทำด้วยตัวเองก่อนขอความช่วยเหลือจากผู้อื่น เนื่องจากไซต์นี้มีไว้สำหรับโปรแกรมเมอร์มืออาชีพและผู้ที่กระตือรือร้นและไม่ใช่เว็บไซต์ช่วยเหลือหรือให้คำปรึกษาหากคุณมีคำถามเกี่ยวกับปัญหาเกี่ยวกับโปรแกรมเฉพาะ แต่ยังไม่ได้ใช้ดีบักเกอร์คำถามของคุณจึงมีแนวโน้มที่จะถูกปิดและลดลงอย่างมาก หากคุณยังคงมีคำถามเช่นนั้นในที่สุดคุณจะถูกบล็อกไม่ให้โพสต์เพิ่มเติม

ดีบักเกอร์สามารถช่วยคุณได้อย่างไร

ด้วยการใช้ดีบักเกอร์คุณจะค้นพบว่าตัวแปรมีค่าที่ไม่ถูกต้องหรือไม่และค่าของมันเปลี่ยนเป็นค่าที่ไม่ถูกต้องในโปรแกรมของคุณ

การใช้สเต็ปเดียวคุณยังสามารถค้นพบว่าการควบคุมเป็นไปตามที่คุณคาดหวังหรือไม่ ตัวอย่างเช่นifสาขาที่ดำเนินการเมื่อคุณคาดว่าควรจะเป็นหรือไม่

หมายเหตุทั่วไปเกี่ยวกับการใช้ดีบักเกอร์

ข้อมูลจำเพาะของการใช้ดีบักเกอร์ขึ้นอยู่กับดีบักเกอร์และภาษาโปรแกรมที่คุณใช้ในระดับที่น้อยกว่า

  • คุณสามารถแนบดีบักเกอร์กับกระบวนการที่รันโปรแกรมของคุณอยู่แล้ว คุณอาจทำถ้าโปรแกรมของคุณค้าง

  • ในทางปฏิบัติมักจะง่ายกว่าในการรันโปรแกรมของคุณภายใต้การควบคุมของดีบักเกอร์ตั้งแต่เริ่มต้น

  • คุณระบุตำแหน่งที่โปรแกรมของคุณควรหยุดการทำงานโดยระบุไฟล์ซอร์สโค้ดและหมายเลขบรรทัดของบรรทัดที่การดำเนินการควรหยุดหรือโดยระบุชื่อของวิธีการ / ฟังก์ชันที่โปรแกรมควรหยุดทำงาน (หากคุณต้องการหยุดเป็น ทันทีที่การดำเนินการเข้าสู่เมธอด) วิธีการทางเทคนิคที่ใช้ดีบักจะทำให้โปรแกรมของคุณเพื่อหยุดเรียกว่าเบรกพอยต์และขั้นตอนนี้จะเรียกว่าการตั้งค่าเบรกพอยต์

  • ดีบักเกอร์ที่ทันสมัยส่วนใหญ่เป็นส่วนหนึ่งของ IDEและมี GUI ที่สะดวกสำหรับการตรวจสอบซอร์สโค้ดและตัวแปรของโปรแกรมของคุณด้วยอินเทอร์เฟซแบบชี้แล้วคลิกสำหรับการตั้งค่าเบรกพอยต์เรียกใช้โปรแกรมของคุณและขั้นตอนเดียว

  • การใช้ดีบักเกอร์อาจเป็นเรื่องยากมากเว้นแต่ไฟล์ที่สามารถเรียกใช้งานได้หรือ bytecode โปรแกรมของคุณจะมีข้อมูลสัญลักษณ์การดีบักและการอ้างอิงข้ามไปยังซอร์สโค้ด คุณอาจต้องคอมไพล์ (หรือคอมไพล์ใหม่) โปรแกรมของคุณแตกต่างกันเล็กน้อยเพื่อให้แน่ใจว่ามีข้อมูลอยู่ หากคอมไพลเลอร์ทำการเพิ่มประสิทธิภาพอย่างครอบคลุมการอ้างอิงโยงเหล่านั้นอาจทำให้สับสนได้ ดังนั้นคุณอาจต้องคอมไพล์โปรแกรมของคุณใหม่โดยปิดการปรับให้เหมาะสม

39 SlugFiller Apr 05 2015 at 19:15

ฉันต้องการเพิ่มว่าดีบักเกอร์ไม่ใช่โซลูชันที่สมบูรณ์แบบเสมอไปและไม่ควรเป็นวิธีแก้จุดบกพร่องเสมอไป ต่อไปนี้เป็นบางกรณีที่เครื่องดีบักอาจไม่ทำงานสำหรับคุณ:

  • ส่วนของโปรแกรมของคุณที่ล้มเหลวนั้นมีขนาดใหญ่มาก (บางทีการแยกส่วนที่ไม่ดีอาจเป็นไปได้?) และคุณไม่แน่ใจว่าจะเริ่มดำเนินการผ่านโค้ดตรงไหน การก้าวผ่านทั้งหมดนี้อาจใช้เวลานานเกินไป
  • โปรแกรมของคุณใช้การเรียกกลับจำนวนมากและวิธีการควบคุมโฟลว์ที่ไม่ใช่เชิงเส้นอื่น ๆ ซึ่งทำให้ดีบักเกอร์สับสนเมื่อคุณทำตามขั้นตอน
  • โปรแกรมของคุณเป็นแบบมัลติเธรด หรือแย่กว่านั้นคือปัญหาของคุณเกิดจากสภาพการแข่งขัน
  • โค้ดที่มีบั๊กจะทำงานหลายครั้งก่อนที่จะบั๊กออกไป สิ่งนี้อาจเป็นปัญหาโดยเฉพาะอย่างยิ่งในลูปหลักหรือแย่กว่านั้นในเอนจินฟิสิกส์ซึ่งปัญหาอาจเป็นตัวเลข แม้แต่การตั้งค่าเบรกพอยต์ในกรณีนี้คุณก็แค่กดปุ่มหลาย ๆ ครั้งโดยที่บั๊กจะไม่ปรากฏขึ้น
  • โปรแกรมของคุณต้องทำงานแบบเรียลไทม์ นี่เป็นเรื่องใหญ่สำหรับโปรแกรมที่เชื่อมต่อกับเครือข่าย หากคุณตั้งค่าเบรกพอยต์ในรหัสเครือข่ายปลายอีกด้านจะไม่รอให้คุณก้าวผ่านมันก็หมดเวลาแล้ว โปรแกรมที่ใช้นาฬิการะบบเช่นเกมที่มี frameskip ก็ไม่ได้ดีไปกว่ากัน
  • โปรแกรมของคุณดำเนินการทำลายบางรูปแบบเช่นการเขียนลงไฟล์หรือส่งอีเมลและคุณต้องการ จำกัด จำนวนครั้งที่คุณต้องเรียกใช้
  • คุณสามารถบอกได้ว่าจุดบกพร่องของคุณเกิดจากค่าที่ไม่ถูกต้องมาถึงฟังก์ชัน X แต่คุณไม่รู้ว่าค่าเหล่านี้มาจากไหน การต้องทำงานผ่านโปรแกรมซ้ำแล้วซ้ำอีกการตั้งค่าจุดพักให้ไกลออกไปอาจเป็นเรื่องยุ่งยากมาก โดยเฉพาะอย่างยิ่งถ้าฟังก์ชัน X ถูกเรียกใช้จากหลาย ๆ ที่ตลอดทั้งโปรแกรม

ในทุกกรณีเหล่านี้การหยุดโปรแกรมกะทันหันอาจทำให้ผลลัพธ์สุดท้ายแตกต่างกันไปหรือการค้นหาบรรทัดเดียวที่เกิดข้อบกพร่องด้วยตนเองนั้นเป็นเรื่องยุ่งยากมากเกินไป สิ่งนี้สามารถเกิดขึ้นได้ไม่ว่าข้อบกพร่องของคุณจะเป็นพฤติกรรมที่ไม่ถูกต้องหรือความผิดพลาด ตัวอย่างเช่นหากความเสียหายของหน่วยความจำทำให้เกิดข้อขัดข้องเมื่อถึงเวลาที่เกิดข้อขัดข้องก็ยังห่างไกลจากจุดที่หน่วยความจำเสียหายครั้งแรกมากเกินไปและไม่มีข้อมูลที่เป็นประโยชน์เหลืออยู่

ทางเลือกอื่นคืออะไร?

ง่ายที่สุดคือการบันทึกและการยืนยัน เพิ่มบันทึกในโปรแกรมของคุณตามจุดต่างๆและเปรียบเทียบสิ่งที่คุณได้รับกับสิ่งที่คุณคาดหวัง ตัวอย่างเช่นดูว่ามีการเรียกใช้ฟังก์ชันที่คุณคิดว่ามีจุดบกพร่องหรือไม่ในตอนแรก ดูว่าตัวแปรที่จุดเริ่มต้นของเมธอดเป็นอย่างที่คุณคิดหรือไม่ ซึ่งแตกต่างจากจุดพักคือโอเคที่จะมีบรรทัดบันทึกหลายบรรทัดซึ่งไม่มีอะไรพิเศษเกิดขึ้น คุณสามารถค้นหาผ่านบันทึกได้ในภายหลัง เมื่อคุณเข้าสู่บรรทัดบันทึกที่แตกต่างจากที่คุณคาดหวังให้เพิ่มมากขึ้นในพื้นที่เดียวกัน จำกัด ขอบเขตให้แคบลงและไกลออกไปจนกว่าจะมีขนาดเล็กพอที่จะบันทึกทุกบรรทัดในพื้นที่ที่มีปัญหา

การยืนยันสามารถใช้เพื่อดักจับค่าที่ไม่ถูกต้องเมื่อเกิดขึ้นแทนที่จะมีผลให้ผู้ใช้ปลายทางมองเห็นได้ ยิ่งคุณตรวจจับค่าที่ไม่ถูกต้องได้เร็วเท่าไหร่คุณก็ยิ่งเข้าใกล้เส้นที่สร้างขึ้นเท่านั้น

การทดสอบ Refactor และหน่วย หากโปรแกรมของคุณมีขนาดใหญ่เกินไปอาจเป็นการคุ้มค่าที่จะทดสอบทีละคลาสหรือทีละฟังก์ชัน ให้อินพุตและดูที่เอาต์พุตและดูว่าสิ่งใดไม่เป็นไปตามที่คุณคาดหวัง ความสามารถในการ จำกัด จุดบกพร่องจากโปรแกรมทั้งหมดให้เหลือเพียงฟังก์ชันเดียวสามารถสร้างความแตกต่างอย่างมากในเวลาดีบัก

ในกรณีที่หน่วยความจำรั่วไหลหรือหน่วยความจำสะดุดให้ใช้เครื่องมือที่เหมาะสมที่สามารถวิเคราะห์และตรวจจับสิ่งเหล่านี้ได้ในขณะรันไทม์ ความสามารถในการตรวจสอบว่ามีการทุจริตเกิดขึ้นที่ใดเป็นขั้นตอนแรก หลังจากนี้คุณสามารถใช้บันทึกเพื่อย้อนกลับไปยังจุดที่มีการนำค่าที่ไม่ถูกต้องมาใช้

โปรดจำไว้ว่าการดีบักเป็นกระบวนการที่ย้อนกลับไป คุณมีผลลัพธ์ - จุดบกพร่อง - และค้นหาสาเหตุซึ่งนำหน้า มันเกี่ยวกับการย้อนกลับไปข้างหลังและน่าเสียดายที่ผู้แก้ปัญหาเพียงแค่ก้าวไปข้างหน้า นี่คือที่ที่การบันทึกที่ดีและการวิเคราะห์หลังการตายสามารถให้ผลลัพธ์ที่ดีกว่ามาก