ฉันมักจะเรียกใช้โปรแกรมเป็น:
./a.out arg1 arg2 <file
ฉันต้องการดีบักโดยใช้ gdb
ฉันตระหนักถึงการset args
ทำงาน แต่ใช้งานได้จากพรอมต์ gdb เท่านั้น
ฉันมักจะเรียกใช้โปรแกรมเป็น:
./a.out arg1 arg2 <file
ฉันต้องการดีบักโดยใช้ gdb
ฉันตระหนักถึงการset args
ทำงาน แต่ใช้งานได้จากพรอมต์ gdb เท่านั้น
คำตอบ:
ส่งผ่านอาร์กิวเมนต์ไปยังrun
คำสั่งจากภายใน gdb
$ gdb ./a.out
(gdb) r < t
Starting program: /dir/a.out < t
$ gdb ./a.out
แล้ว(gdb) r < t arg1 arg2
ที่ทำงานที่ดีสำหรับฉัน ในกรณีของฉันa.out = nft
arg1 = import
arg2 = json
และt = file containing json rules
คุณสามารถทำได้:
gdb --args path/to/executable -every -arg you can=think < of
ความมหัศจรรย์ที่เกิด--args
ขึ้น
เพียงพิมพ์run
ในคอนโซลคำสั่ง gdb เพื่อเริ่มการดีบัก
--args
ก็ไม่มีข้อโต้แย้งใด ๆ ที่ส่งผ่านไปยังปฏิบัติการได้ดังนั้นมันจึงไม่ค่อยชัดเจน
argv[0]
คือชื่อของปฏิบัติการ
gdb
ตัวเองไปยังof
ไฟล์และส่งผลให้ gdb พยายามรันคำสั่งจากมัน
หากคุณต้องการมีrun
คำสั่งเปล่าในgdb
การรันโปรแกรมด้วยการเปลี่ยนเส้นทางและการขัดแย้งคุณสามารถใช้set args
:
% gdb ./a.out
(gdb) set args arg1 arg2 <file
(gdb) run
ฉันไม่สามารถทำสิ่งเดียวกันกับ--args
พารามิเตอร์ได้ทำให้gdb
เกิดการเปลี่ยนเส้นทางอย่างรุนแรงเช่น
% gdb --args echo 1 2 "<file"
(gdb) show args
Argument list to give program being debugged when it is started is "1 2 \<file".
(gdb) run
...
1 2 <file
...
อันนี้เปลี่ยนเส้นทางอินพุตของ gdb จริงๆไม่ใช่สิ่งที่เราต้องการที่นี่
% gdb --args echo 1 2 <file
zsh: no such file or directory: file
เริ่ม GDB ในโครงการของคุณ
ไปที่ไดเรกทอรีโครงการซึ่งคุณได้รวบรวมโครงการปฏิบัติการแล้ว ออกคำสั่ง gdb และชื่อของไฟล์เรียกทำงานด้านล่าง:
gdb projectExecutablename
สิ่งนี้จะเริ่มขึ้น gdb พิมพ์ต่อไปนี้: GNU gdb (Ubuntu 7.11.1-0ubuntu1 ~ 16.04) 7.11.1 ลิขสิทธิ์ (C) 2016 มูลนิธิซอฟต์แวร์เสรีปี 2016 ............... .................................. พิมพ์ "apropos word" เพื่อค้นหาคำสั่งที่เกี่ยวข้องกับ "word" .. . การอ่านสัญลักษณ์จาก projectExecutablename ... เรียบร้อย (gdb)
ก่อนที่คุณจะเริ่มโปรแกรมของคุณทำงานคุณต้องการตั้งค่าเบรกพอยต์ของคุณ คำสั่ง break อนุญาตให้คุณทำเช่นนั้น หากต้องการตั้งค่าเบรกพอยต์ที่จุดเริ่มต้นของฟังก์ชันชื่อ main:
(gdb) b หลัก
เมื่อคุณได้รับพรอมต์ (gdb) แล้วคำสั่ง run จะเริ่มต้นการเรียกใช้งานได้ หากโปรแกรมที่คุณกำลังดีบักต้องการอาร์กิวเมนต์บรรทัดคำสั่งใด ๆ คุณต้องระบุโปรแกรมเหล่านั้นในคำสั่ง run หากคุณต้องการรันโปรแกรมของฉันในไฟล์ "xfiles" (ซึ่งอยู่ในโฟลเดอร์ "mulder" ในไดเรกทอรีโครงการ) คุณจะทำสิ่งต่อไปนี้:
(gdb) r mulder / xfiles
หวังว่านี่จะช่วยได้
คำเตือน: การแก้ปัญหานี้จะไม่ระเบิดก็จะดัดแปลงมาจากhttps://web.stanford.edu/class/cs107/guide_gdb.html คำแนะนำสั้น ๆ นี้จะได้รับการ gdb ส่วนใหญ่อาจได้รับการพัฒนาที่ Stanford University
มันจะดีหรือไม่ที่จะพิมพ์debug
ต่อหน้าคำสั่งใด ๆ เพื่อให้สามารถดีบักได้gdb
ระดับเชลล์?
ด้านล่างมันฟังก์ชั่นนี้ มันใช้งานได้กับ:
"$program" "$@" < <(in) 1> >(out) 2> >(two) 3> >(three)
นี่คือการเรียกที่คุณไม่สามารถควบคุมอะไรก็ได้ทุกอย่างเป็นตัวแปรสามารถมีช่องว่าง linefeeds และเชลล์เมตาอักขระ ในตัวอย่างนี้in
, out
, two
และthree
มีคำสั่งอื่น ๆ ที่ใช้โดยพลการหรือข้อมูลการผลิตซึ่งจะต้องไม่ได้รับอันตราย
bash
ฟังก์ชั่นดังต่อไปนี้จะเรียกใช้gdb
เกือบหมดจดในสภาพแวดล้อมเช่น [ สรุป ]
debug()
{
1000<&0 1001>&1 1002>&2 \
0</dev/tty 1>/dev/tty 2>&0 \
/usr/bin/gdb -q -nx -nw \
-ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\"" exec' \
-ex r \
--args "$@";
}
ตัวอย่างเกี่ยวกับวิธีใช้: เพียงพิมพ์ debug
ด้านหน้า:
ก่อน:
p=($'\n' $'I\'am\'evil' " yay ")
"b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)
หลังจาก:
p=($'\n' $'I\'am\'evil' " yay ")
debug "b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)
แค่นั้นแหละ. gdb
ตอนนี้ก็แน่นอนไม่มีเกมง่ายๆที่จะแก้ปัญหาด้วย ยกเว้นรายละเอียดเล็กน้อยหรือมากกว่านั้น:
gdb
ไม่เลิกโดยอัตโนมัติและด้วยเหตุนี้ทำให้ IO gdb
เปลี่ยนเส้นทางเปิดให้บริการจนถึงคุณออก แต่ฉันเรียกคุณลักษณะนี้ว่า
คุณไม่สามารถส่งผ่านไปยังโปรแกรมเช่นเดียวกับargv0
exec -a arg0 command args
ต่อไปนี้ควรทำเคล็ดลับนี้: หลังจากexec-wrapper
การเปลี่ยนแปลงไป"exec
"exec -a \"\${DEBUG_ARG0:-\$1}\"
มี FDs มากกว่า 1,000 เปิดซึ่งโดยปกติจะปิด หากนี่เป็นปัญหาให้เปลี่ยน0<&1000 1>&1001 2>&1002
เป็นอ่าน0<&1000 1>&1001 2>&1002 1000<&- 1001>&- 1002>&-
คุณไม่สามารถเรียกใช้ตัวแก้ไขสองตัวพร้อมกัน อาจมีปัญหาหากคำสั่งอื่นใช้/dev/tty
(หรือ STDIN) ในการแก้ไขปัญหาที่แทนที่ด้วย/dev/tty
"${DEBUGTTY:-/dev/tty}"
ในบางประเภท TTY อื่น ๆtty; sleep inf
แล้วใช้พิมพ์ TTY (i. E. /dev/pts/60
) DEBUGTTY=/dev/pts/60 debug command arg..
สำหรับการแก้จุดบกพร่องในขณะที่ นั่นคือพลังของเชลล์ชินกับมัน!
ฟังก์ชั่นอธิบาย:
1000<&0 1001>&1 1002>&2
ย้าย 3 FDs แรกออกไป
0</dev/tty 1>/dev/tty 2>&0
เรียกคืน 3 FDs แรกให้ชี้ไปที่ TTY ปัจจุบันของคุณ gdb
เพื่อให้คุณสามารถควบคุม/usr/bin/gdb -q -nx -nw
รันการgdb
เรียกใช้gdb
บนเชลล์-ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\""
สร้าง wrapper เริ่มต้นซึ่งจะกู้คืน 3 FDs แรกซึ่งถูกบันทึกไว้ที่ 1,000 ขึ้นไป-ex r
เริ่มโปรแกรมโดยใช้ exec-wrapper
--args "$@"
ผ่านการขัดแย้งตามที่กำหนดมันไม่ง่ายเลยเหรอ?
r
สั้นrun
และคุณสามารถทำตามได้ทุกข้อ เช่นเดียวกับในคำถามนี้มันจะเป็น:r arg1 arg2 <file
หรืออาจเป็นrun arg1 arg2 <file