Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@JosephTremoulet
Created September 6, 2019 22:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JosephTremoulet/2689c5ed21d7be5543cfcb70d548e0bc to your computer and use it in GitHub Desktop.
Save JosephTremoulet/2689c5ed21d7be5543cfcb70d548e0bc to your computer and use it in GitHub Desktop.
Out-of-process minidump examples
// This is the process we're going to capture a minidump of.
//
// compile with g++ -g -o busyloop busyloop.cpp
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
void loop() {
volatile static int g = 0;
while (!g++) {
--g;
}
}
int main(int argc, char** argv) {
// Send SIGUSR1 to parent to indicate we've started
// and it can go ahead and capture dump.
pid_t ppid = getppid();
kill(ppid, SIGUSR1);
loop();
return 0;
}
$ lldb ./busyloop --core dump.md
(lldb) target create "./busyloop" --core "dump.md"
Core file '.../dump.md' (x86_64) was loaded.
(lldb) bt
* thread #1, stop reason = signal SIGSTOP
* frame #0: 0x0000000000400582 busyloop`loop() at busyloop.cpp:8
frame #1: 0x00000000004005c1 busyloop`main(argc=1, argv=0x00007ffd78776db8) at busyloop.cpp:15
frame #2: 0x00007ff946d2b830 libc-2.23.so`__libc_start_main(main=(busyloop`main at busyloop.cpp:12), argc=1, argv=0x00007ffd78776db8, init=<unavailable>, fini=<unavailable>, rtld_fini=<unavailable>, stack_end=0x00007ffd78776da8) at libc-start.c:291
frame #3: 0x0000000000400499 busyloop`_start + 41
(lldb) q
$ lldb ./busyloop --core dump2.md
(lldb) target create "./busyloop" --core "dump2.md"
Core file '.../dump2.md' (x86_64) was loaded.
(lldb) bt
* thread #1, stop reason = signal SIGSTOP
frame #0: 0xffffffffffffffff
(lldb) q
// This launches 'busyloop', waits for its signal, and
// then captures a minidump of it
//
// compile with g++ -I ~breakpad/src/src -std=c++14 -pthread -g -o test test.cpp -L~breakpad/src/src/client/linux -lbreakpad_client -lpthread
#include "client/linux/minidump_writer/minidump_writer.h"
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <cstdlib>
#include <cstdio>
int main(int argc, char** argv) {
// launch busyloop via fork and execv so that this will be
// the parent process and have permission to attach
pid_t pid = fork();
if (pid) {
// This is the parent. Wait for sigusr1 so we know that
// the child has transitioned to busyloop
sigset_t usr1;
sigemptyset(&usr1);
sigaddset(&usr1, SIGUSR1);
sigprocmask(SIG_BLOCK, &usr1, nullptr);
sigwaitinfo(&usr1, nullptr);
// Now capture the state in a minidump and write it to dump.md
google_breakpad::MappingList emptyMappingList;
google_breakpad::AppMemoryList emptyAppMemoryList;
bool success = google_breakpad::WriteMinidump(
"dump.md", pid, nullptr, 0, emptyMappingList, emptyAppMemoryList);
if (!success) {
perror("Failed to write dump");
return 1;
}
int result = kill(pid, SIGKILL);
if (result) {
perror("kill returned error");
return 1;
}
return 0;
}
// This is the child. Spawn busyloop
char busyloop[] = "busyloop";
char * args[] = { busyloop, nullptr };
execv(busyloop, args);
perror("execl returned");
return 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment