Linux'ta gdb için programlı olarak C veya C ++ kodunda kesme noktası ayarlayın


105

Linux'ta gdb için çalışacak programatik olarak C veya C ++ kodunda nasıl bir kesme noktası belirleyebilirim?

Yani:

int main(int argc, char** argv)
{
    /* set breakpoint here! */
    int a = 3;
    a++;  /*  In gdb> print a;  expect result to be 3 */
    return 0;
}

8
Çok fazla bir yan not (nitpick için özür dilerim), ancak taşınabilirlik konusunda endişeleniyorsanız, muhtemelen doğruluk konusunda da endişeleniyorsunuzdur - dolayısıyla int maindeğil void main.
Stuart Golodetz

@Stuart - Düzeltildi. Bunu bir süre önce yapmalıydım.
J. Polfer

4
@ J.Polfer: return 0Gerçi gerekli değil ve sadece gürültü!
Yörüngede Hafiflik Yarışları

Yanıtlar:


107

Bunun bir yolu, bir kesinti belirtmektir:

#include <csignal>

// Generate an interrupt
std::raise(SIGINT);

C'de:

#include <signal.h>
raise(SIGINT);

GÜNCELLEME : MSDN , Windows'un gerçekten desteklemediğini belirtirSIGINT , bu nedenle taşınabilirlik bir endişeyse, muhtemelen kullanmanız daha iyi olur SIGABRT.


Evet, bu işletim sistemleri / derleyiciler / hata ayıklayıcılar arasında çalışmalıdır.
Håvard S

1
Diğer hata ayıklayıcıları bilmiyorum, ancak gdb sinyal işleme konusunda oldukça esnektir .
Cascabel


1
Windows, MSVC'de __debug_break, DebugBreak veya _asm {int 3} kullanabilirsiniz.
Fernando Gonzalez Sanchez

2
@FernandoGonzalezSanchez: burada gördüğünüz gibi aslında işlev adı __debugbreak()ve DEĞİL __debug_break()
Morix Dev

27

Üzerinde çalıştığım bir projede şunu yapıyoruz:

raise(SIGABRT);  /* To continue from here in GDB: "signal 0". */

(Bizim durumumuzda, eğer bu hata ayıklayıcının dışında meydana gelirse, mümkünse bir çökme raporu oluşturmak istedik. SIGABRT kullanmamızın bir nedeni de budur. Bunu Windows, Mac ve Linux'ta taşınabilir bir şekilde yapmak birkaç girişimde bulundu. Sonunda birkaç deneme yaptık #ifdefs, burada yararlı bir şekilde yorumlanmıştır: http://hg.mozilla.org/mozilla-central/file/98fa9c0cff7a/js/src/jsutil.cpp#l66 .)


2
Her zamanki gibi pencereler diğerleri gibi görünmüyor :)
mathk

Programı duraklatılmış durumda programlamaya devam etmek için "sinyal 0" vermek mümkün müdür? Bu noktadan itibaren "c" verilmeden "n" veya "s" kullanabilmek güzel olurdu.
Jason Doucette

2
Eğer gerçekten sadece duraklama programı istiyorsanız @JasonDoucette, bir eklemek isteyebilirsiniz breakpoint()(Boş olduğunu ya da sadece bir baskı deyimi içerebilir) Programda fonksiyonu ve ekleme break breakpointadresinden Müşteri ~/.gdbinit.
Jason Orendorff

26

Buraya bakarak şu yolu buldum:

void main(int argc, char** argv)
{
    asm("int $3");
    int a = 3;
    a++;  //  In gdb> print a;  expect result to be 3
}

Bu bana bir dokunuş hile gibi görünüyor. Ve bunun yalnızca x86 mimarisinde çalıştığını düşünüyorum.


3
Ve yalnızca AT&T derleme sözdizimini destekleyen derleyicilerle. Özellikle, Microsoft'un derleyicisi ( cl.exe) bu sözdizimini desteklemez, ancak farklı bir sözdizimi kullanır.
Håvard S

soru linux hakkındaydı, bu yüzden gcc sözdiziminin x86 için çalışacağını varsayabiliriz.
js.

BTW - x86 makinemde yukarıdakileri denedim ve işe yaradı. Bunu yapmanın daha iyi bir yolu olup olmadığını merak ettim. Görünüşe göre var.
J. Polfer

2
Pencerelerde mingw kullanıyorum, böylece diğer öneriler bana yardımcı olamaz. SIGINT sinyalinin yükseltilmesi sadece uygulamayı sonlandırır, SIGTRAP mingw başlıklarında tanımlanmaz ... int komutunun kullanılması aslında SIGTRAP ve gdb sonlarını uygun satıra güzelce gönderir.
Machta

Linux'ta int 3bir SIGTRAP yükseltir.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

12

__asm__("int $3"); çalışmalı:

int main(int argc, char** argv)
{
    /* set breakpoint here! */
    int a = 3;
    __asm__("int $3");
    a++;  /*  In gdb> print a;  expect result to be 3 */
    return 0;
}

1
Ben mi #defineben sözdizimi hatırlamak toi zorunda kalmamak olduğunu, bu. assert()Hata ayıklayıcıyı durdurduğumdan beri kodumun her yerine serpiştirdim, bazen yerine, tüm değişkenleri ve yığını inceleyelim. Ve tabii ki, iddia gibi, onu üretim kodu için kaldırmak zorunda değilim
Mawg, Monica

"Linux" ve "GDB" nin soru kısıtlamaları, hiçbir şey olmasa bile taşınabilirlik uğruna her zaman son çare olabilecek bir araya getirme dışında birçok seçenek sunduğunda bunun 10 olumlu oyu olması ilginçtir. Lütfen diğer cevaplardan bazılarına bakın.
Benjamin Crawford Ctrl-Alt-Tut

5

Yazılım kesme noktaları için özel sinyali kullanmayan bu kadar çok yanıt görmek hayal kırıklığı yaratıyor SIGTRAP:

#include <signal.h>

raise(SIGTRAP); // At the location of the BP.

1

OS X'te arayabilirsin std::abort()(Linux'ta aynı olabilir)


Hangi kütüphane?
Alex

Bu, standart C ++ kitaplığının bir parçasıdır ve C ++ 11 uyumlu derleyicilerin bulunduğu çapraz platformdur. Ancak bu, bu durumda yükseltmek için gerçekten uygun bir sinyal olmayan SIGABRT'yi yükseltir.
Benjamin Crawford Ctrl-Alt-Tut
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.