หยุดพักเมื่อค่าเปลี่ยนแปลงโดยใช้ดีบักเกอร์ Visual Studio


198

มีวิธีการวางนาฬิกาบนตัวแปรหรือไม่และมี Visual Studio break เฉพาะเมื่อค่านั้นเปลี่ยนไปหรือไม่

มันจะทำให้ง่ายขึ้นมากในการค้นหาปัญหาของรัฐหากิน

สามารถทำได้หรือไม่

เงื่อนไขเบรกพอยต์ยังต้องมีชุดเบรกพอยต์และฉันควรตั้งนาฬิกาและให้ Visual Studio ตั้งค่าเบรกพอยต์เมื่อมีการเปลี่ยนแปลงสถานะ


แต่เบรกพอยต์จะไม่ส่งผลกระทบอะไรเลยเว้นแต่ว่ามีเงื่อนไขดังนั้นคุณสามารถวางเบรกพอยต์ของคุณได้ทุกที่ (เช่น Setter) และนำมาจากที่นั่น หรือฉันกำลังพลาดอะไรอยู่?
Oskar

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

ขอโทษที่ไม่เคยเห็นทางที่ไกลที่สุดเท่าที่ฉันรู้ว่าหมาเป็นวิธีที่จะไป
ออสการ์

1
ฉันหวังว่าจะได้พบข่าวที่ดีกว่า; vs2010 บ่งชี้ว่าไม่มีการเปลี่ยนแปลงmsdn.microsoft.com/en-us/library/350dyxd0.aspxมีเพียงภาษาท้องถิ่น c ++ เท่านั้นที่มี @Scottgu คุณสามารถทำได้ดีกว่านี้!
gerryLowry

คำตอบ:


134

ในเมนู Visual Studio 2005:

Debug -> เบรกพอยต์ใหม่ -> เบรกพอยต์ข้อมูลใหม่

Enter:

&myVariable

38
มีให้สำหรับรหัสที่จัดการหรือไม่ ฉันเห็นตัวเลือกนี้ปิดใช้งานสำหรับโครงการ C # โปรดจำไว้ว่าการอ่านบางที่นี่เป็นคุณสมบัติที่ใช้งานได้ยากในการแก้ไขข้อบกพร่องของแอพที่ได้รับการจัดการโดยเฉพาะอย่างยิ่งกับตัวเก็บขยะที่เกี่ยวข้อง
Gulzar Nazim

27
ใช้ได้เฉพาะกับรหัสที่ไม่มีการจัดการเท่านั้นโชคไม่ดีที่: msdn.microsoft.com/en-us/library/350dyxd0.aspx
Josh Kodroff

17
คุณยังสามารถแปลงฟิลด์เป็นคุณสมบัติชั่วคราวและวางเบรกพอยต์บนตัวรับหรือตัวตั้งค่า
Jon Davis

12
ตัวเลือก "Data เบรกพอยต์" ภายใต้ "Debug -> เบรกพอยต์ใหม่" ถูกปิดใช้งาน .. มีความคิดใด ๆ มันยังคงปิดการใช้งานไม่ว่าฉันจะดีบั๊กหรือไม่ ฉันใช้ Visual Studio 2015
jbb

2
ล่าช้าเล็กน้อย แต่ @jbb สำหรับฉันจะเปิดใช้งานเฉพาะเมื่อฉันหยุดที่เบรกพอยต์ขณะทำการดีบัก
Allball103

27

คุณยังสามารถเลือกที่จะทำลายรหัสอย่างชัดเจน:

// Assuming C#
if (condition)
{
    System.Diagnostics.Debugger.Break();
}

จาก MSDN:

Debugger.Break: หากไม่มีการเชื่อมต่อดีบักเกอร์ผู้ใช้จะถูกถามว่าต้องการแนบดีบั๊กหรือไม่ ถ้าใช่ตัวดีบักเริ่มต้นแล้ว หากมีการแนบดีบักตัวดีบักจะถูกส่งสัญญาณด้วยเหตุการณ์เบรกพอยต์ของผู้ใช้และดีบักเกอร์จะหยุดการทำงานของกระบวนการเช่นเดียวกับที่พบกับจุดพักดีบั๊ก

นี่เป็นเพียงทางเลือกเท่านั้น การตั้งค่าเบรกพอยต์แบบมีเงื่อนไขใน Visual Studio ตามที่อธิบายไว้ในความคิดเห็นอื่นเป็นตัวเลือกที่ดีกว่า


2
FWIW ที่มีการแก้ไขและดำเนินการต่อฉันชอบที่จะทำเช่นนี้: IME, เบรกพอยต์แบบมีเงื่อนไขเป็นสิ่งที่ยุ่งเหยิง
Mark Sowul

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

26

โพสต์เก่าจริงๆ แต่ในกรณีที่มีคนไม่รู้จัก ...

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

public bool IsUpdated
{
    get;
    set;    //set breakpoint on this line
}

ปรับปรุง

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

public bool IsUpdated { get; set; }

5
แม้ว่าคุณสมบัติการใช้งานอัตโนมัติจะอยู่ในหนึ่งบรรทัดเช่นชื่อผู้ใช้สาธารณะสตริง {ชุด; ได้รับ; } ผู้ใช้สามารถเน้น getter หรือ setter และสามารถกด F9 เพื่อเพิ่มเบรกพอยต์
Abdul Rauf

@AbdulRaufMujahid เยี่ยมมาก!
Craig

13

ลองนึกภาพคุณมีคลาสที่เรียกว่า A พร้อมกับประกาศต่อไปนี้

class A  
{  
    public:  
        A();

    private:
        int m_value;
};

คุณต้องการให้โปรแกรมหยุดทำงานเมื่อมีคนแก้ไขค่าของ "m_value"

ไปที่คำจำกัดความของคลาสและใส่เบรกพอยต์ในตัวสร้างของ A

A::A()
{
    ... // set breakpoint here
}

เมื่อเราหยุดโปรแกรม:

Debug -> เบรกพอยต์ใหม่ -> เบรกพอยต์ข้อมูลใหม่ ...

ที่อยู่: & (สิ่งนี้ -> m_value)
จำนวนไบต์: 4 (เนื่องจาก int มี 4 ไบต์)

ตอนนี้เราสามารถดำเนินการโปรแกรมต่อได้ โปรแกรมดีบั๊กจะหยุดทำงานเมื่อมีการเปลี่ยนแปลงค่า

คุณสามารถทำเช่นเดียวกันกับคลาสที่สืบทอดหรือคลาสผสม

class B
{
   private:
       A m_a;
};

ที่อยู่: & (สิ่งนี้ -> m_a.m_value)

หากคุณไม่ทราบจำนวนไบต์ของตัวแปรที่คุณต้องการตรวจสอบคุณสามารถใช้ตัวดำเนินการ sizeof ได้

ตัวอย่างเช่น:

// to know the size of the word processor,  
// if you want to inspect a pointer.
int wordTam = sizeof (void* ); 

หากคุณดูที่ "Call stack" คุณจะเห็นฟังก์ชั่นที่เปลี่ยนค่าของตัวแปร


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

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

9

เปลี่ยนตัวแปรเป็นคุณสมบัติและเพิ่มเบรกพอยต์ในเมธอด set ตัวอย่าง:

private bool m_Var = false;
protected bool var
{
    get { 
        return m_var;
    }

    set { 
        m_var = value;
    }
}

3

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

แต่น่าเศร้าที่ฉันไม่พบเครื่องมือใด ๆ ที่จะอนุญาตให้คุณทำเช่นเดียวกันกับคุณสมบัติหรือตัวแปรใด ๆ


3

ผมจำได้ว่าวิธีการที่คุณอธิบายโดยใช้Visual Basic 6.0 ใน Visual Studio, วิธีเดียวที่ฉันได้พบเพื่อให้ห่างไกลโดยการระบุสภาพเบรกพอยต์


2

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


2

ดังที่ Peter Mortensen เขียนว่า:

ในเมนู Visual Studio 2005:

Debug -> เบรกพอยต์ใหม่ -> เบรกพอยต์ข้อมูลใหม่

ป้อน: & myVariable

ข้อมูลเพิ่มเติม:

เห็นได้ชัดว่าระบบจะต้องรู้ที่อยู่ในหน่วยความจำที่จะดู ดังนั้น - ตั้งเบรกพอยต์ปกติเพื่อการเริ่มต้นของmyVariable (หรือmyClass.m_Variable) - เรียกใช้ระบบและรอจนกว่ามันจะหยุดที่เบรกพอยต์นั้น - ตอนนี้รายการเมนูถูกเปิดใช้งานและคุณสามารถดูตัวแปรโดยการป้อน&myVariableหรืออินสแตนซ์โดยการป้อน&myClass.m_Variableหรือตัวอย่างเช่นโดยการป้อนตอนนี้ที่อยู่มีการกำหนดไว้อย่างดี

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


1

คุณสามารถใช้หน่วยความจำ watchpoint ในรหัสที่ไม่มีการจัดการ ไม่แน่ใจว่าสิ่งเหล่านี้มีอยู่ในรหัสที่มีการจัดการหรือไม่


1

คุณอาจจะสามารถทำให้การใช้ฉลาดของDebugBreak ()ฟังก์ชั่น


ว่าอย่างไร โดยเรียกใช้เธรดแยกต่างหากในการวนรอบแน่นและเรียกใช้ DebugBreak () เมื่อใดก็ตามที่มีการเปลี่ยนแปลงเกิดขึ้น
ใกล้

@nalpy ตัวอย่างเช่นคุณสามารถติดตามตำแหน่งที่myVariableใช้และเก็บค่าหลังจากใช้ในpreviousValueตัวแปรเสริมจากนั้นเรียก DebugBreak () เมื่อmyVariable!=previousValue; จากนั้นคุณจะรู้ได้ว่าบล็อกโค้ดใดที่myVariableมีการเปลี่ยนแปลง แต่ฉันยอมรับว่าทางออกของแอชลี่นั้นดีที่สุด
เช็ด

1

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


1

อัพเดทในปี 2562:

ตอนนี้ได้รับการสนับสนุนอย่างเป็นทางการแล้วใน Visual Studio 2019 Preview 2 สำหรับ. Net Core 3.0 หรือสูงกว่า แน่นอนคุณอาจต้องคำนึงถึงความเสี่ยงที่อาจเกิดขึ้นจากการใช้งาน Preview รุ่นของ IDE ฉันคิดว่าในอนาคตอันใกล้นี้จะรวมอยู่ใน Visual Studio อย่างเป็นทางการ

https://blogs.msdn.microsoft.com/visualstudio/2019/02/12/break-when-value-changes-data-breakpoints-for-net-core-in-visual-studio-2019/

โชคดีที่จุดพักข้อมูลไม่มีเอกสิทธิ์ C ++ อีกต่อไปเพราะตอนนี้พร้อมใช้งานสำหรับ. NET Core (3.0 หรือสูงกว่า) ใน Visual Studio 2019 Preview 2 แล้ว!

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