ฉันต้องการบังคับให้ดัมพ์หลักที่ตำแหน่งเฉพาะในแอปพลิเคชัน C ++ ของฉัน
ฉันรู้ว่าฉันทำได้โดยทำสิ่งที่ชอบ:
int * crash = NULL;
*crash = 1;
แต่อยากทราบว่ามีวิธีที่สะอาดกว่านี้ไหม?
ฉันกำลังใช้ Linux อยู่
ฉันต้องการบังคับให้ดัมพ์หลักที่ตำแหน่งเฉพาะในแอปพลิเคชัน C ++ ของฉัน
ฉันรู้ว่าฉันทำได้โดยทำสิ่งที่ชอบ:
int * crash = NULL;
*crash = 1;
แต่อยากทราบว่ามีวิธีที่สะอาดกว่านี้ไหม?
ฉันกำลังใช้ Linux อยู่
คำตอบ:
การเพิ่มสัญญาณหมายเลข 6 ( SIGABRT
ใน Linux) เป็นวิธีหนึ่งที่ทำได้ (แต่โปรดทราบว่า SIGABRT ไม่จำเป็นต้องเป็น 6 ในการใช้งาน POSIX ทั้งหมดดังนั้นคุณอาจต้องการใช้SIGABRT
ค่านี้เองหากเป็นอย่างอื่นที่ไม่ใช่ quick'n 'รหัสดีบักสกปรก)
#include <signal.h>
: : :
raise (SIGABRT);
การโทรabort()
จะทำให้เกิดการถ่ายโอนข้อมูลหลักและคุณสามารถทำได้โดยไม่ต้องยุติกระบวนการของคุณด้วยการโทรfork()
ตามด้วยabort()
ในลูกเท่านั้น - ดูคำตอบนี้สำหรับรายละเอียด
ulimit -c unlimited
จากคำตอบของ Suvesh Pratapa ช่วยฉันได้มากสำหรับคำตอบนี้
ไม่กี่ปีที่ผ่านมา Google ได้เปิดตัวห้องสมุดcoredumper
ภาพรวม
ไลบรารี coredumper สามารถคอมไพล์ลงในแอปพลิเคชันเพื่อสร้างแกนกลางของโปรแกรมที่กำลังทำงานอยู่ - โดยไม่ต้องยุติ รองรับการถ่ายโอนข้อมูลหลักทั้งแบบเดี่ยวและแบบมัลติเธรดแม้ว่าเคอร์เนลจะไม่รองรับไฟล์คอร์แบบมัลติเธรด
Coredumper จัดจำหน่ายภายใต้เงื่อนไขของ BSD License
ตัวอย่าง
นี่ไม่ใช่ตัวอย่างที่สมบูรณ์ เพียงแค่ให้คุณรู้สึกว่า coredumper API มีลักษณะอย่างไร
#include <google/coredumper.h> ... WriteCoreDump('core.myprogram'); /* Keep going, we generated a core file, * but we didn't crash. */
ไม่ใช่สิ่งที่คุณขอ แต่อาจจะดีกว่านี้ก็ได้ :)
ตามที่ระบุไว้ในการจัดการสัญญาณสัญญาณใด ๆ ที่มีการดำเนินการที่ระบุว่าเป็น 'แกน' จะบังคับให้มีการถ่ายโอนข้อมูลหลัก ตัวอย่างบางส่วน ได้แก่ :
SIGQUIT 3 Core Quit from keyboard
SIGILL 4 Core Illegal Instruction
SIGABRT 6 Core Abort signal from abort(3)
SIGFPE 8 Core Floating point exception
SIGSEGV 11 Core Invalid memory reference
ตรวจสอบให้แน่ใจว่าคุณเปิดใช้งานการทิ้งหลัก:
ulimit -c unlimited
setrlimit(RLIMIT_CORE, &core_limits);
ใช้ได้ผ่านทาง#include <sys/resource.h>
. คุณสร้างโครงสร้างของชนิดrlimit
จากนั้นตั้งค่าrlim_cur
และrlim_max
สมาชิก
#include <stdlib.h> // C
//#include <cstdlib> // C++
void core_dump(void)
{
abort();
}
abort()
โดยตรง
วิงวอน
abort();
ที่เกี่ยวข้องบางครั้งคุณต้องการการติดตามย้อนกลับโดยไม่มีการถ่ายโอนข้อมูลหลักจริงและอนุญาตให้โปรแกรมทำงานต่อไป: ตรวจสอบฟังก์ชัน glibc backtrace () และ backtrace_symbols (): http://www.gnu.org/s/libc/ manual / html_node / Backtraces.html
อีกวิธีในการสร้าง core ดัมพ์:
$ bash
$ kill -s SIGSEGV $$
เพียงสร้างอินสแตนซ์ใหม่ของการทุบตีและฆ่าด้วยสัญญาณที่ระบุ $$
เป็น PID ของเปลือก มิฉะนั้นคุณจะฆ่า bash ปัจจุบันของคุณและจะออกจากระบบเทอร์มินัลปิดหรือตัดการเชื่อมต่อ
$ bash
$ kill -s SIGABRT $$
$ bash
$ kill -s SIGFPE $$
bash -c 'kill -SIGSEGV $$'
ขึ้นได้
คุณสามารถใช้kill (2)เพื่อส่งสัญญาณ
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
ดังนั้น,
kill(getpid(), SIGSEGV);
บางครั้งอาจเหมาะสมที่จะทำสิ่งนี้:
int st = 0;
pid_t p = fork();
if (!p) {
signal(SIGABRT, SIG_DFL);
abort(); // having the coredump of the exact copy of the calling thread
} else {
waitpid(p, &st, 0); // rip the zombie
}
// here the original process continues to live
ปัญหาอย่างหนึ่งของแนวทางง่ายๆนี้คือเธรดเดียวเท่านั้นที่จะถูกตัดทอน
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("\n");
printf("Process is aborting\n");
abort();
printf("Control not reaching here\n");
return 0;
}
ใช้แนวทางนี้ทุกที่ที่คุณต้องการ :)
#include <assert.h>
.
.
.
assert(!"this should not happen");