1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
/*
* sb_gdb.c
*
* Helpers for autolaunching gdb.
*
* Copyright 1999-2012 Gentoo Foundation
* Licensed under the GPL-2
*/
#include "headers.h"
#include "sbutil.h"
static int __sb_connect_gdb(void *vpid)
{
char pid[10];
snprintf(pid, sizeof(pid), "%i", (pid_t)(uintptr_t)vpid);
unsetenv(ENV_LD_PRELOAD);
return /*sb_unwrapped_*/execlp("gdb", "gdb",
"--quiet",
"--pid", pid,
"-ex", "set _gdb_poller = 0",
"-ex", "fin",
"-ex", "bt full",
"-ex", "echo \\n",
"-ex", "f",
NULL);
}
#define STACK_SIZE 4096
#ifndef HAVE_CLONE
# ifdef HAVE___CLONE2
/* Hrm, maybe they have clone2 */
# define clone(fn, stack, flags, arg) \
__clone2(fn, stack, STACK_SIZE, flags, arg, NULL, NULL, NULL)
# else
/* Fake it with fork() ... not as safe, but not much else we can do */
static int fake_clone(int (*fn)(void *), void *child_stack, int flags, void *arg)
{
pid_t pid = fork();
switch (pid) {
case 0:
_exit(fn(arg));
default:
return pid;
}
}
# define clone(...) fake_clone(__VA_ARGS__)
# endif
#endif
void sb_gdb(void)
{
char stack[STACK_SIZE * 2];
pid_t pid = getpid();
/* Put the child stack in the middle so we don't have to worry about
* the direction of growth. Most grown down, but some grow up!@
*/
if (clone(__sb_connect_gdb, stack + STACK_SIZE, 0, (void *)(uintptr_t)pid) != -1) {
volatile int _gdb_poller = 1;
while (_gdb_poller);
}
}
void sb_maybe_gdb(void)
{
if (is_env_on("SANDBOX_GDB")) {
sb_einfo("attempting to autolaunch gdb; please wait ...\n\n");
sb_gdb();
}
}
|