พวกเขาดีบักข้อผิดพลาดการแบ่งกลุ่มก่อนหน่วยความจำที่ได้รับการป้องกันอย่างไร


20

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

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


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

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

3
แม้ตอนนี้ความผิดพลาดของตัวชี้จำนวนมากก็ไม่ได้ทำให้เกิด segfault ที่ดี
CodesInChaos

1
ในช่วงเวลาของ DOS หน่วยความจำที่ได้รับการป้องกันมีอยู่แล้วในระบบปฏิบัติการอื่น
mouviciel

คำตอบ:


36

ฉันสามารถเห็นโปรแกรมเมอร์ DOS เล่นซอและกระแทกทั้งระบบปฏิบัติการเมื่อเขาทำผิดพลาด

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

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


3
ในความเป็นจริงฉันหวังว่า "คนแก่" จะตอบคำถามของฉัน ไม่มีอะไรจะชนะประสบการณ์มือแรก ขอบคุณ
Bart Friederichs

6
ลองเขียนโค้ดเมื่อฮาร์ดแวร์พร้อมใช้งานสำหรับการดีบั๊กทุกคืนตั้งแต่เวลา 02:00 น. ถึง 06:00 น. โดยแน่นอนว่าเพื่อนร่วมงานของคุณไม่ได้สำรองไว้สำหรับการแก้ไขข้อบกพร่อง
MSalters

@MSalters แน่นอน! ในงานแรกของฉันเราสามารถจองสล็อตในวันอาทิตย์ได้ตั้งแต่เวลา 07.00 น. ถึง 24.00 น. - การปฏิบัติจริงเลมเปบอก :-)
Ross Patterson

2
ฉันจำได้ว่าเขียนโปรแกรมแรกของฉันลงบนกระดาษที่เดินทางกลับบ้านจากมหาวิทยาลัย วันถัดไปเมื่อฉันสามารถชกต่อยและเรียกใช้มันก็ไร้ที่ติ ;-)
Jan Doggen

1
@ JanDoggen เหมือนกันสำหรับฉัน เมื่อคุณลองครั้งเดียวคุณจะลองนับดูสิ
nalply

23

ย้อนกลับไปในวันของฉันเราไม่ได้มีการป้องกันหน่วยความจำและทุกธุรกิจที่โก๋! เราใช้ printf เพื่อพิจารณาว่าเราอยู่ที่ไหนในโปรแกรมและเราชอบมัน !

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

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

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


2
ฟรี Mallocs!
คริส

1
ทุก ๆ ครั้งแม้กระทั่งทุกวันนี้แม้แต่ call stack และ state variable ก็ไร้ประโยชน์อย่างเต็มที่ในการพิจารณาว่า heck ผิดพลาดไปอย่างไรและจะแก้ไขได้อย่างไร โดยเฉพาะอย่างยิ่งถ้าคุณมีซอฟต์แวร์ที่ซับซ้อนที่มีสถานะที่เป็นไปได้จำนวนมากซึ่งบางส่วนมีการพึ่งพาซึ่งกันและกัน หลงทางเดียวเขียนได้ทุกที่และยืนยันการละเว้นสำหรับเงื่อนไขที่รับประกันสามารถนำคุณไปที่นั่น
CVn

1
@ MichaelKjörlingฉันคิดว่าสำหรับสิ่งที่เกี่ยวข้องกับการค้นพบข้อผิดพลาดในโปรแกรมเราได้ดำเนินการเฉพาะสำหรับสิ่งที่เกี่ยวข้องกับการค้นหาทริกเกอร์ข้อผิดพลาด แต่เรายังมีอีกหลายไมล์เพื่อค้นหาสาเหตุของข้อผิดพลาดเหล่านี้ การยืนยันช่วยให้ฉันมีสติอย่างแน่นอน :)
Neil

6

ดี ..

segfault เป็นตัวบ่งชี้ที่ดีจริง ๆ ว่ามีบางอย่างผิดปกติ แต่คุณยังต้องค้นหาสาเหตุที่แท้จริง ดังนั้นหากคุณถามคำถามคุณจะค้นหาสาเหตุที่แท้จริงได้อย่างไรกว่าคำตอบนั้นไม่แตกต่างจากวันนี้มากนัก แน่นอนว่าภาษาและเครื่องมือต่างๆนั้นง่ายต่อการใช้งาน แต่ taktik ทั่วไปเหมือนกัน:

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

ในระดับนามธรรมคุณมีสามวิธี: 1. ทำงานกับโค้ด 2. ดูโปรแกรมในขณะที่มันทำงาน 3. ดูผลลัพธ์หลังจากทำสิ่งที่โง่

btw ข้อผิดพลาดของตัวชี้ไม่จำเป็นต้องสร้าง segfault

ในฐานะโปรแกรมเมอร์ Amiga ฉันใช้มันมากทีเดียว และใช่รีสตาร์ทที่ปฏิบัติทั่วไป


4

บน IBM 360 การรันงานแบตช์ Fortran เราเคยได้รับ hex core dumps การถ่ายโอนข้อมูลดังกล่าวอาจมีความหนาเท่ากับกระดาษเครื่องพิมพ์สีเขียวขาว มันจะบอกสิ่งที่ลงทะเบียนและจากนั้นเราสามารถย้อนกลับและคิดออกว่าโปรแกรมกำลังทำอะไร เราสามารถหาแต่ละรูทีนย่อยและหาที่เก็บที่อยู่ผู้ส่งดังนั้นเราจะเห็นบริบท มันจะช่วยให้มีรายชื่อแอสเซมเบลอร์ของโปรแกรม


2

เมื่อฉันทำงานแก้ไขข้อผิดพลาดในซอฟต์แวร์ Windows 3.1 Presentation ที่มีชื่อเสียง

ฉันมีข้อบกพร่องซึ่งเมื่อมันเกิดขึ้นก็ทำให้ Blue Screen of Death

ข้อผิดพลาดเกิดขึ้นเฉพาะเมื่อมีการดำเนินการวนรอบที่แน่นอนมากกว่า 1,000 ครั้ง ฉันใช้คุณสมบัติขั้นสูงของตัวดีบักเกอร์เพื่อให้จุดพักผ่านไป 1,000 ครั้งจากนั้นฉันก็เหยียบโปรแกรมอย่างระมัดระวัง ทุกครั้งที่ฉันไปไกลเกินไปหรือข้ามการเรียกใช้ฟังก์ชันซึ่งมีจุดบกพร่อง Windows Blue Screened

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

การแก้จุดบกพร่องทักษะและความเพียรเป็นวิธีแก้ปัญหา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.