อย่าหยุดดีบักเกอร์ที่ข้อยกเว้นนั้นเมื่อถูกโยนและจับ


91

ในเครื่องมือ / ข้อยกเว้นฉันได้ตั้งค่าตัวเลือกให้ดีบักเกอร์หยุดเมื่อเกิดข้อยกเว้น ไม่ว่าจะจับได้หรือไม่.

ฉันจะยกเว้นข้อยกเว้นของกฎนั้นได้อย่างไร ที่ไหนสักแห่งในรหัสของฉันมีข้อยกเว้นที่ถูกจับได้ซึ่งเป็นส่วนหนึ่งของตรรกะของโปรแกรม ดังนั้นฉันจึงไม่ต้องการให้ข้อยกเว้นนั้นหยุดดีบักเกอร์ทุกครั้งที่ถูกโจมตี

ตัวอย่าง: ฉันต้องการละเว้นข้อยกเว้น nullreference (ซึ่งถูกจับได้) ในบรรทัด 344 ฉันต้องการหยุดที่ข้อยกเว้นอื่น ๆ ทั้งหมด


6
เมื่อข้อยกเว้นนี้เป็นส่วนหนึ่งของตรรกะการเขียนโปรแกรมของคุณ (ลองคิดดูว่าถ้าคุณต้องใช้มันด้วยวิธีนี้จริงๆ) - อย่างน้อยก็ควรเป็นข้อยกเว้นที่สร้างขึ้นเอง วิธีนี้คุณสามารถใช้วิธีแก้ปัญหาของ Brian
tanascius

นี่คือปัญหา: stackoverflow.com/questions/1957907/…
MichaelD

2
@tanascius - +1 ฉันเห็นด้วยในกรณีส่วนใหญ่ข้อยกเว้นไม่ใช่วิธีที่ดีที่สุดในการตัดสินใจอย่างมีเหตุผล อย่างไรก็ตามในบางกรณีเช่นเมื่อการแยกส่วนการจัดการข้อยกเว้นเป็นสิ่งที่หลีกเลี่ยงไม่ได้ในบางครั้งดังนั้น throw> catch> handle จึงเป็นทางเลือกเดียวที่สมเหตุสมผล
jpierson

2
@ Ando ขอโทษที่ไม่ดีของฉัน การตรวจสอบหลายแท็บพร้อมกันนั้นมีประสิทธิภาพ แต่ไม่ถูกต้องเสมอไป

3
@tanascius: คุณอาจยังต้องจับข้อยกเว้นของเฟรมเวิร์กที่ทราบก่อนจึงจะสามารถตอบสนองได้ คำแนะนำของคุณไม่สามารถทำได้เสมอไป
Dan Puzey

คำตอบ:


40

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


31
จากคำตอบของ malinger และประสบการณ์ของฉันคำตอบนี้ดูเหมือนจะไม่ถูกต้อง DebuggerStepThroughแอตทริบิวต์ไม่ได้มีผลต่อพฤติกรรมการดีบักเกอร์ที่มีข้อยกเว้นโอกาสแรก
Michael Petrotta

5
@ ทิมฉันทดสอบแล้วก็ไม่หยุด ชำระเงินคำตอบของฉัน: stackoverflow.com/questions/1420390/3455100#3455100
Shimmy Weitzhandler

1
+1 ทำงานใน VS2010 สำหรับรหัส. NET 4.0 และ Silverlight 4 ที่บริสุทธิ์สำหรับข้อยกเว้นที่ไม่สามารถจัดการได้
Mike Post

6
หมายเหตุสำคัญ:วิธีนี้ใช้ไม่ได้กับเมธอดประเภท async-await เพิ่มเติมที่นี่
i3arnon

8
ตาม MSDN DebuggerStepThroughแอตทริบิวต์ไม่มีความหมายกับ CLR ถูกตีความโดย debuggers ดูเหมือนว่ามันจะทำงานได้ไม่น่าเชื่อถือภายใต้สถานการณ์ที่หลากหลายและDebuggerHiddenจะทำงานได้อย่างน่าเชื่อถือstackoverflow.com/a/3455100/141172
Eric J.

65

DebuggerHidden เป็นเพื่อนของคุณ!

รันไทม์ภาษาทั่วไปไม่เชื่อมโยงความหมายกับแอ็ตทริบิวต์นี้ มีไว้เพื่อใช้โดยผู้ดีบั๊กซอร์สโค้ด ตัวอย่างเช่นตัวดีบักเกอร์ Visual Studio 2005 ไม่หยุดในวิธีการที่ทำเครื่องหมายด้วยแอตทริบิวต์นี้และไม่อนุญาตให้ตั้งค่าเบรกพอยต์ในวิธีการ แอตทริบิวต์ดีบักเกอร์อื่น ๆ ที่ได้รับการยอมรับโดยโปรแกรมดีบักเกอร์ Visual Studio 2005 คือ DebuggerNonUserCodeAttribute และ DebuggerStepThroughAttribute

ทดสอบกับ VS2010 และใช้งานได้ดี

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

โปรดทราบว่าทั้งสองตัวเลือกทำงานได้ในขณะนี้ด้วยวิธีการบล็อก iteratorหรือasync วิธีการ สิ่งนี้สามารถแก้ไขได้ในการอัปเดต Visual Studio ในภายหลัง


ทำงานบน VS2008 คุณต้องใช้วิธีนี้กับวิธีการทั้งหมดรวมถึงการสกัดกั้นไม่เช่นนั้นคุณจะทำลายที่อื่น
Mark Heath

1
ฉันเพิ่มแอตทริบิวต์นั้นลงในเมธอดและดีบักเกอร์ก็หยุดการเรียกใช้วิธีการแทน ฉันพลาดอะไรไปรึเปล่า?
Doogal

1
นั่นคือสิ่งที่ควรจะเป็น เพื่อหลีกเลี่ยงสิ่งนั้นคุณจะต้องจัดการกับข้อยกเว้น ... หรือไม่ก็ทำเครื่องหมายวิธีการโทรDebuggerHiddenเช่นกัน ...
Shimmy Weitzhandler

1
โปรดทราบว่าแอตทริบิวต์ DebuggerStepThrough ควรเพียงพอที่จะหลีกเลี่ยงการทำลายข้อยกเว้น DebuggerHidden ทำหน้าที่เหมือนการรวมกันของทั้ง DebuggerNonUserCode และ DebuggerStepThrough Attribute
jpierson


14

DebuggerStepThrough เป็นวิธีที่จะใช้เพื่อป้องกันไม่ให้ดีบักเกอร์แตกในวิธีการที่มีการลอง / จับ

แต่จะใช้งานได้ก็ต่อเมื่อคุณไม่ได้ยกเลิกการเลือกตัวเลือก "Enable Just My Code (Managed Only)" ในการตั้งค่าทั่วไปของตัวเลือกการดีบักของ Visual Studio (เมนูเครื่องมือ / ตัวเลือกการแก้จุดบกพร่อง / ทั่วไป)

ข้อมูลเพิ่มเติมเกี่ยวกับแอตทริบิวต์นั้นในhttp://abhijitjana.net/2010/09/22/tips-on-debugging-using-debuggerstepthrough-attribute/

DebuggerHidden จะป้องกันไม่ให้ Debugger แสดงเมธอดที่เกิดข้อยกเว้น แต่จะแสดงวิธีแรกบนสแต็กซึ่งไม่ได้ทำเครื่องหมายด้วยแอตทริบิวต์นั้น ...


1
โปรดทราบว่าสิ่งนี้ไม่ทำงานตามค่าเริ่มต้นใน VS 2015 อีกต่อไปโปรดดูบล็อก VS สำหรับวิธีการเปิดใช้งาน
bhh

น่าเศร้าที่การ
โจนาธานอัลเลน

13

แอตทริบิวต์ที่ระบุในคำตอบอื่น ๆ (และDebuggerNonUserCodeแอตทริบิวต์อื่น ๆ เช่นแอตทริบิวต์) ไม่ทำงานในลักษณะเดียวกันตามค่าเริ่มต้นใน Visual Studio 2015 อีกต่อไปตัวดีบักเกอร์จะทำลายข้อยกเว้นในตลาดวิธีการที่มีแอตทริบิวต์เหล่านั้นซึ่งแตกต่างจาก VS. เวอร์ชันเก่ากว่า หากต้องการปิดการเพิ่มประสิทธิภาพการทำงานที่เปลี่ยนแปลงพฤติกรรมคุณต้องเปลี่ยนการตั้งค่ารีจิสทรี:

reg add HKCU\Software\Microsoft\VisualStudio\14.0_Config\Debugger\Engine /v AlwaysEnableExceptionCallbacksOutsideMyCode /t REG_DWORD /d 1

ข้อมูลเพิ่มเติมสามารถพบได้บนบล็อกภาพสตูดิโอ

(นี่น่าจะเป็นความคิดเห็นในคำตอบด้านบน แต่ฉันมีตัวแทนไม่เพียงพอ)


3

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

หากรหัสของคุณแสดงข้อยกเว้นที่เป็นปัญหาฉันจะทำให้เป็นข้อยกเว้นที่กำหนดเองซึ่งได้มาจากสิ่งที่เหมาะสมจากนั้นปิดใช้งานการทำลายการดีบักในประเภทที่ได้รับนี้

การปิดการใช้งานระบบ exeptions เป็น NullReferenceException จะส่งผลต่อระบบทั้งหมดซึ่งแน่นอนว่าไม่เป็นที่ต้องการในระหว่างการพัฒนา

โปรดทราบว่ามีสองประเภทของพฤติกรรมหยุดพักสำหรับข้อยกเว้น:

  • โยน: ถ้าเลือกจะหยุดทันทีที่มีการโยนข้อยกเว้นประเภทนี้
  • ผู้ใช้ไม่สามารถจัดการได้: หากเลือกจะหยุดพักเฉพาะเมื่อข้อยกเว้นประเภทนี้ไม่ได้รับการจัดการโดย try / catch

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


3
การเพิ่มแอตทริบิวต์ DebuggerStepThrough ให้กับวิธีการใน Visual Studio 2010 จะป้องกันไม่ให้ดีบักเกอร์หยุดข้อยกเว้นที่ไม่สามารถจัดการได้โดยวิธีนี้
Tim Murphy

ฉันทดสอบแล้วและมันไม่ได้ป้องกัน มันยังคงหยุดอยู่
Shimmy Weitzhandler

1
@Shimmy - ทำงานให้ฉัน! ตรวจสอบให้แน่ใจว่าคุณใช้ DebuggerStepThrough กับแต่ละวิธีจากจุดที่ถูกโยนไปจนถึงจุดที่คุณต้องการให้ข้อยกเว้นปรากฏให้เห็นภายใน call stack หากคุณจับข้อยกเว้นและจัดการภายในลำดับชั้นการเรียกที่ซึ่งวิธีการทั้งหมดได้รับการตกแต่งด้วย DebuggerStepThrough คุณไม่ควรเห็น VS break ในข้อยกเว้นนั้น
jpierson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.