ตั้งค่าเบรกพอยต์ในโค้ด C หรือ C ++ โดยทางโปรแกรมสำหรับ gdb บน Linux


107

ฉันจะตั้งค่าเบรกพอยต์ในโค้ด C หรือ C ++ โดยทางโปรแกรมที่จะทำงานกับ gdb บน Linux ได้อย่างไร

ได้แก่ :

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
มากสังเกตด้าน (ขอโทษที่ nitpick) แต่ถ้าคุณกังวลเกี่ยวกับการพกพาแล้วคุณอาจจะยังกังวลเกี่ยวกับความถูกต้อง - เพราะฉะนั้นมากกว่าint main void main
Stuart Golodetz

@Stuart - คงที่. ควรจะทำเมื่อสักครู่ที่ผ่านมา
J. Polfer

4
@ J.Polfer: แม้ว่าreturn 0มันไม่จำเป็นและเป็นเพียงเสียงรบกวน!
Lightness Races ใน Orbit

คำตอบ:


107

วิธีหนึ่งคือส่งสัญญาณการขัดจังหวะ:

#include <csignal>

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

ใน C:

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

UPDATE : MSDN ระบุว่า Windows ไม่ได้โดดสนับสนุนดังนั้นหากพกพาเป็นกังวลคุณอาจดีกว่าการใช้SIGINTSIGABRT


ใช่สิ่งนี้ควรใช้ได้กับระบบปฏิบัติการ / คอมไพเลอร์ / ดีบักเกอร์
Håvard S

1
ผมไม่ทราบว่าแก้จุดบกพร่องอื่น ๆ แต่ gdb สวยความยืดหยุ่นเกี่ยวกับการจัดการสัญญาณ
Cascabel

4
เราพบว่า SIGTRAP ดีกว่าในบาง Unices
JBRWilkinson

1
ใน Windows, MSVC คุณสามารถใช้ __debug_break, DebugBreak หรือ _asm {int 3} ได้
Fernando Gonzalez Sanchez

2
@FernandoGonzalezSanchez: จริงๆแล้วชื่อฟังก์ชันคือ__debugbreak()และไม่ใช่ __debug_break()อย่างที่คุณเห็นที่นี่
Morix Dev

27

ในโครงการที่ฉันทำเราทำสิ่งนี้:

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

(ในกรณีของเราเราต้องการหยุดทำงานอย่างหนักหากสิ่งนี้เกิดขึ้นนอกดีบักเกอร์สร้างรายงานข้อขัดข้องหากเป็นไปได้นั่นเป็นเหตุผลหนึ่งที่เราใช้ SIGABRT การทำสิ่งนี้แบบพกพาใน Windows, Mac และ Linux ต้องใช้ความพยายามหลายครั้งเราจบลงด้วยการไม่กี่ครั้ง #ifdefs แสดงความคิดเห็นอย่างเป็นประโยชน์ที่นี่: http://hg.mozilla.org/mozilla-central/file/98fa9c0cff7a/js/src/jsutil.cpp#l66 )


2
ตามปกติ windows จะไม่เหมือนแบบอื่น :)
mathk

เป็นไปได้หรือไม่ที่จะออก "สัญญาณ 0" เพื่อให้โปรแกรมดำเนินการต่อในสถานะหยุดชั่วคราว จะเป็นการดีที่จะสามารถใช้ 'n' หรือ 's' ได้จากจุดนี้โดยไม่มีการออก 'c'
Jason Doucette

2
@JasonDoucette หากคุณต้องการให้โปรแกรมหยุดชั่วคราวจริงๆคุณอาจต้องการเพิ่มbreakpoint()ฟังก์ชันในโปรแกรมของคุณ (อาจว่างเปล่าหรือมีเพียงคำสั่งพิมพ์) และเพิ่มลงbreak breakpointใน~/.gdbinitไฟล์.
Jason Orendorff

26

เมื่อดูที่นี่ฉันพบวิธีต่อไปนี้:

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

นี่ดูเหมือนจะเป็นการแฮ็กสำหรับฉัน และฉันคิดว่าสิ่งนี้ใช้ได้กับสถาปัตยกรรม x86 เท่านั้น


3
และเฉพาะกับคอมไพเลอร์ที่สนับสนุนไวยากรณ์แอสเซมบลี AT&T โดยเฉพาะอย่างยิ่งคอมไพเลอร์ของ Microsoft ( cl.exe) ไม่สนับสนุนไวยากรณ์นี้ แต่ใช้ไวยากรณ์อื่น
Håvard S

คำถามเกี่ยวกับ linux ดังนั้นฉันเดาว่าเราสามารถสันนิษฐานได้ว่าไวยากรณ์ gcc จะใช้ได้กับ x86
js.

BTW - ฉันได้ลองทำตามขั้นตอนข้างต้นบนเครื่อง x86 ของฉันแล้วและมันได้ผล ฉันอยากรู้ว่ามีวิธีที่ดีกว่านี้ไหม ดูเหมือนว่ามี
J.Polfer

2
ฉันใช้ mingw บน windows ดังนั้นคำแนะนำอื่น ๆ ไม่สามารถช่วยฉันได้ การเพิ่มสัญญาณ SIGINT เพียงแค่ยุติแอปพลิเคชัน SIGTRAP ไม่ได้กำหนดไว้ในส่วนหัว mingw ... การใช้คำสั่ง int จะส่ง SIGTRAP และ gdb แตกในบรรทัดที่เหมาะสม
Machta

ใน Linux int 3เพิ่ม SIGTRAP
Ciro Santilli 郝海东冠状病六四事件法轮功

12

__asm__("int $3"); ควรทำงาน:

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
ฉันชอบ#defineสิ่งนี้เพื่อที่ฉันจะได้ไม่ต้องจำไวยากรณ์ ฉันโรยมันตลอดโค้ดของฉันบางครั้งก็แทนที่assert()เนื่องจากการหยุด debiugger ให้ฉันตรวจสอบตัวแปรและสแต็กทั้งหมด และแน่นอนเช่นเดียวกับการยืนยันฉันไม่จำเป็นต้องลบออกเพื่อใช้เป็นรหัสการผลิต
Mawg กล่าวว่าคืนสถานะ Monica

ที่น่าสนใจคือมีการโหวต 10 คะแนนเมื่อข้อ จำกัด ของคำถาม "Linux" และ "GDB" ให้ตัวเลือกมากมายนอกเหนือจากการใช้แอสเซมบลีซึ่งควรเป็นทางเลือกสุดท้ายสำหรับการพกพาหากไม่มีอะไรอื่น โปรดดูคำตอบอื่น ๆ
Benjamin Crawford Ctrl-Alt-Tut


1

บน OS X คุณสามารถโทรได้std::abort()(อาจเหมือนกันบน Linux)


ห้องสมุดไหน?
Alex

นี่เป็นส่วนหนึ่งของไลบรารี C ++ มาตรฐานและเป็นข้ามแพลตฟอร์มที่มีคอมไพเลอร์ที่สอดคล้องกับ C ++ 11 อย่างไรก็ตามสิ่งนี้ทำให้เกิด SIGABRT ซึ่งไม่ใช่สัญญาณที่เหมาะสมที่จะเพิ่มขึ้นในกรณีนี้
Benjamin Crawford Ctrl-Alt-Tut
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.