2013-07-10 32 views
5

Jak zatrzymać, gdy warunek w instrukcji if jest spełniony, podczas debugowania? Na przykład:Jak zatrzymać, gdy warunek w instrukcji if jest spełniony, debugowanie

if (!check()) { 
    int a = 0; 
} 

Int a = 0; jest fikcyjny kod, a następnie umieszczam tam punkt przerwania. Jeśli umieścisz punkt przerwania wewnątrz pustej pętli if, debugger się nie zatrzyma, zatrzymuje się tylko przy instrukcjach, które może wykonać. Nawet jeśli masz int; tylko deklaracja to się nie skończy.

Czy mogę to zrobić w inny sposób, niż pisać fałszywy kod?

Dzięki

+7

Jaka jest Twoja platforma? Większość debuggerów powinna mieć możliwość użycia warunkowego punktu przerwania. – Bart

+0

"zatrzymuje się tylko zgodnie z instrukcjami, które może wykonać", co sprawia, że ​​zastanawiam się, czy możesz skompilować je w taki sposób, aby zoptymalizować te. – PlasmaHH

+0

Największe pytanie brzmi, jak sądzę, dlaczego masz puste ciało oświadczenia? –

Odpowiedz

10

Czy mogę to zrobić w inny sposób, niż zamiast pisania fałszywego kodu?

Tak!

W debugerze powinieneś być w stanie dodać punkt przerwania i ustawić go tak, aby łamał się tylko wtedy, gdy spełniony jest określony warunek. Jak to zrobić, zależy od twojego IDE, ale w moim mogę kliknąć prawym przyciskiem myszy punkt przerwania w ramce edytora kodu lub w oddzielnym oknie Punktów przerwania i wybrać Właściwości z menu podręcznego. Potem się to okno:

Breakpoint properties dialog with Condition set

Widać, że mam ustawić własność „Warunek”, który zostanie oceniony za każdym razem kod hitów, które przerwania - ale punkt przerwania będzie tylko złamać, gdy warunek to true. Tj., Jeśli check() zwraca true, gdy wszystko jest w porządku, spowoduje przerwanie, gdy check() wróci false.

To powoduje spowolnienie programu, jeśli ta metoda jest często nazywana, ponieważ zazwyczaj do oceny takiego wyrażenia debugger musi (wewnętrznie) włamać się i ocenić coś. Ale to jest zgrabna funkcjonalność. Uwaga wszystkie inne właściwości, które można ustawić, jak również, i to nawet nie dostanie się do tego, co okno wygląda po kliknięciu przycisku Zaawansowane ...

Aby odpowiedzieć na inne pytania:

Gdybym umieścić Punkt przerwania wewnątrz pustej pętli jeśli debugger nie zatrzyma się , zatrzymuje się tylko przy instrukcjach, które może wykonać. Nawet jeśli wykonasz int a; tylko deklaracja, że ​​się nie zatrzyma.

Jeśli blok if (bez pętli) jest pusty, to nie ma na co go zatrzymać. Może zatrzymać się tylko na rzeczywistym kodzie. int a; jest po prostu zmienną deklaracją; w przypadku typów prostych nie generuje się do tego kodu. (Może to być dla bardziej złożonych typów, choć MyClass a; na przykład, ponieważ nazwałbym konstruktora). Nawet jeśli piszesz trochę więcej kodu:

if (!check()) { 
    int a; 
    a = 5; 
    b = a; 
} 

kompilator nie może nadal generowania kodu dla tego, ponieważ może się domyślić, że kod tak naprawdę nigdy nic nie robi.Zależy to w pewnym stopniu od ustawień optymalizacji, ale niektóre kompilatory zoptymalizują je nawet bez żadnego konkretnego ustawienia optymalizacji.

Czasami może się przydać złamanie kodu, zamiast korzystania z IDE, z różnych powodów (czasami tylko z szybkości oceny stanu). W tej sytuacji zwykle używam wywołania funkcji, aby się włamać, ponieważ kompilator nie wie, funkcja nie modyfikuje stan programu i nie mogą zoptymalizować ją:

if (!check()) { 
    rand(); // <- breakpoint here 
} 

Ale zazwyczaj właściwe wykorzystanie IDE i debugger cech jest lepszym rozwiązaniem.

Edytuj: odkąd to się upvoted (dzięki chłopaki) Myślałem, że dodaję inne podejście, dla kompletności. Punkt przerwania oprogramowania/debuggera występuje z interrupt 3, which is patched in by the debugger. Instrukcja montażu int 3 ma tylko jeden bajt, więc można ją załatać za pomocą dowolnej innej instrukcji; kiedy program się zepsuje, stara instrukcja może zostać tymczasowo naprawiona. Ale oprócz debuggera umieszczającego to w locie, możesz umieścić go w kodzie.

Innymi słowy, możesz wymusić na swoim programie złamanie kodu (i zostać złapanym przez debuggera, jeśli nie działasz pod debuggerem, może to powodować problemy, zazwyczaj twój program zostanie przerwany) przez coś takiego . Składnia zależy od środowiska:

if (!check()) { 
    __asm int 3 
} 

lub nawet lepiej, unikając środowiskową zależne od kodu, wiele C++ kompilatory mają intrinsics lub makra, takich jak DebugBreak(); lub __debugbreak które można wykorzystać tak:

if (!check()) { 
    DebugBreak(); 
} 

Po uruchomieniu programu pod debuggerem okaże się, że wykonanie zostanie przerwane w tym wierszu.

Nie ma powodu, aby używać tego normalnie. Jeden widziałem to niestandardowy moduł obsługi asert, który włamuje się do debuggera, gdy asercja się nie powiedzie, ale pozwala kontynuować wykonywanie.

0

Użyj assertion. Jest przeznaczony do sprawdzania błędów czasowych debugowania. Wykonanie zatrzymuje się natychmiast, jeśli warunek jest fałszywy (równa się zero).

+0

Czy nie jest, gdy warunek jest _nie_ spełniony? – Dahaka

+0

Oto również dobry przykład: http://stackoverflow.com/questions/253212/what-are-assertions-and-why-would-you-use-them – Fuv

+3

OP wydawał się chcieć _debug break_, nie 'abort 'program. –

Powiązane problemy