Skip to content

Commit 6ed9e0b

Browse files
committed
Add libsymtrap.so
1 parent 2aa05b1 commit 6ed9e0b

File tree

2 files changed

+179
-2
lines changed

2 files changed

+179
-2
lines changed

Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ LDFLAGS =
1212

1313
SRC = $(wildcard *.c)
1414
ALL = $(SRC:%.c=%)
15-
ALT = vdso
15+
ALT = vdso libsymtrap.so
1616
DEF := $(filter-out $(ALT), $(ALL))
1717
TXT = cc-version.txt cc-defines.txt
1818

@@ -29,7 +29,10 @@ $(RSB): %: %.rs Makefile
2929
$(RC) $<
3030

3131
vdso: %: %.c Makefile
32-
$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS) -ldl
32+
$(CC) $(CFLAGS) $< -o $@ -ldl $(LDFLAGS)
33+
34+
libsymtrap.so: %: %.c Makefile
35+
$(CC) $(CFLAGS) -fPIC -shared $< -o $@ -Wl,-z,initfirst -ldl $(LDFLAGS)
3336

3437
cc-version.txt: Makefile
3538
echo CC=$(CC) > $@

libsymtrap.so.c

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
#define _GNU_SOURCE
2+
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <unistd.h>
6+
#include <stdarg.h>
7+
#include <dlfcn.h>
8+
#include <execinfo.h>
9+
#include <time.h>
10+
#include <sys/ioctl.h>
11+
#include <sys/types.h>
12+
#include <sys/stat.h>
13+
#include <fcntl.h>
14+
#include <string.h>
15+
16+
17+
/*
18+
* This library is intended to be preloaded so that it can abort at a specific
19+
* point and generate a core dump for analysis. It needs to be manually altered
20+
* to match specific case.
21+
*
22+
* Notes:
23+
* -funwind-tables might be needed on some architectures (arm, riscv)
24+
* for backtrace() to work
25+
* -rdynamic can help make backtrace() output more readable
26+
*
27+
* Backtrace output can be further decoded with add2line:
28+
* $ addr2line -fp -e ./elf addr
29+
*
30+
*/
31+
32+
33+
#define DLSYM_CHECK(handle) do { \
34+
if ((handle) != NULL) { \
35+
/* fprintf(stdout, "libsymtrap.so: wrapping %s()\n", __func__); */ \
36+
} else { \
37+
fprintf(stderr, "%s\n", dlerror()); \
38+
abort(); \
39+
} \
40+
} while (0)
41+
42+
43+
static void do_abort(void)
44+
{
45+
int size;
46+
void *buffer[64];
47+
48+
size = backtrace(buffer, sizeof(buffer));
49+
fprintf(stderr, "backtrace() returned %d addresses:\n", size);
50+
backtrace_symbols_fd(buffer, size, STDERR_FILENO);
51+
abort();
52+
}
53+
54+
55+
#if 1
56+
/*
57+
* extern int clock_gettime (clockid_t __clock_id, struct timespec *__tp) __THROW;
58+
*/
59+
int clock_gettime(clockid_t clock_id, struct timespec *tp)
60+
{
61+
static int (*__clock_gettime)(clockid_t, struct timespec *) = NULL;
62+
static unsigned long count = 0;
63+
64+
if (__clock_gettime == NULL) {
65+
__clock_gettime = (int (*)(clockid_t, struct timespec *))dlsym(RTLD_NEXT, "clock_gettime");
66+
DLSYM_CHECK(__clock_gettime);
67+
}
68+
69+
/*
70+
* app under certain load generated 3~5k calls / second so the idea was
71+
* to abort but only when file flag exists
72+
*/
73+
if (++count % 4000 == 0) {
74+
int ret;
75+
76+
ret = access("/tmp/symtrap_clock_gettime", F_OK);
77+
if (!ret)
78+
do_abort();
79+
}
80+
81+
return __clock_gettime(clock_id, tp);
82+
}
83+
#endif
84+
85+
#if 1
86+
/*
87+
* extern int ioctl (int __fd, unsigned long int __request, ...) __THROW;
88+
*/
89+
int ioctl(int fd, unsigned long int request, ...)
90+
{
91+
int ret;
92+
va_list args;
93+
static int (*__ioctl)(int, unsigned long int, ...) = NULL;
94+
unsigned long int ioc;
95+
96+
if (__ioctl == NULL) {
97+
__ioctl = (int (*)(int, unsigned long int, ...))dlsym(RTLD_NEXT, "ioctl");
98+
DLSYM_CHECK(__ioctl);
99+
}
100+
101+
/*
102+
* ioctl from strace:
103+
* ioctl(11, _IOC(0, 0x64, 0x05, 0x65), 0xb60a4bb8);
104+
*/
105+
ioc = _IOC(0, 0x64, 0x05, 0x65);
106+
107+
/* abort on matching ioctl */
108+
if (request == ioc)
109+
do_abort();
110+
111+
va_start(args, request);
112+
ret = __ioctl(fd, request, args);
113+
va_end(args);
114+
115+
return ret;
116+
}
117+
#endif
118+
119+
#if 1
120+
/*
121+
* match this file name
122+
*/
123+
#define FILE_PATH "/dev/input/event1"
124+
125+
/*
126+
* extern int open (const char *__file, int __oflag, ...) __nonnull ((1));
127+
*/
128+
int open(const char *pathname, int flags, ...)
129+
{
130+
int ret;
131+
va_list args;
132+
static int (*__open)(const char *, int, ...) = NULL;
133+
134+
if (__open == NULL) {
135+
__open = (int (*)(const char *, int, ...))dlsym(RTLD_NEXT, "open");
136+
DLSYM_CHECK(__open);
137+
}
138+
139+
/* abort on matching file name */
140+
if (!strcmp(pathname, FILE_PATH))
141+
do_abort();
142+
143+
va_start(args, flags);
144+
ret = __open(pathname, flags, args);
145+
va_end(args);
146+
147+
return ret;
148+
}
149+
150+
/*
151+
* extern int open64 (const char *__file, int __oflag, ...) __nonnull ((1));
152+
*/
153+
int open64(const char *pathname, int flags, ...)
154+
{
155+
int ret;
156+
va_list args;
157+
static int (*__open64)(const char *, int, ...) = NULL;
158+
159+
if (__open64 == NULL) {
160+
__open64 = (int (*)(const char *, int, ...))dlsym(RTLD_NEXT, "open64");
161+
DLSYM_CHECK(__open64);
162+
}
163+
164+
/* abort on matching file name */
165+
if (!strcmp(pathname, FILE_PATH))
166+
do_abort();
167+
168+
va_start(args, flags);
169+
ret = __open64(pathname, flags, args);
170+
va_end(args);
171+
172+
return ret;
173+
}
174+
#endif

0 commit comments

Comments
 (0)