v2 / vlib / builtin / gc_debugger_linux.h
55 lines · 48 sloc · 1.37 KB · c25d479cb59fae2751dc83a1ba3e47b08ab6755d
Raw
1#ifndef V_BUILTIN_GC_DEBUGGER_LINUX_H
2#define V_BUILTIN_GC_DEBUGGER_LINUX_H
3
4#if defined(__linux__)
5#include <fcntl.h>
6#include <string.h>
7#include <unistd.h>
8
9#pragma weak __data_start
10#pragma weak data_start
11#pragma weak _end
12
13extern int __data_start[];
14extern int data_start[];
15extern int _end[];
16
17static inline int v__gc_can_register_main_data_roots_linux(void) {
18 void* data_start_ptr = __data_start != NULL ? (void*)__data_start : (void*)data_start;
19 void* data_end_ptr = (void*)_end;
20 return data_start_ptr != NULL && data_end_ptr != NULL && data_start_ptr < data_end_ptr;
21}
22
23static inline int v__gc_debugger_present_linux(void) {
24 int fd = open("/proc/self/status", O_RDONLY);
25 if (fd < 0) {
26 return 0;
27 }
28 char buf[4096];
29 ssize_t n = read(fd, buf, sizeof(buf) - 1);
30 (void)close(fd);
31 if (n <= 0) {
32 return 0;
33 }
34 buf[n] = '\0';
35 char* tracer_pid = strstr(buf, "TracerPid:");
36 if (tracer_pid == NULL) {
37 return 0;
38 }
39 tracer_pid += sizeof("TracerPid:") - 1;
40 while (*tracer_pid == ' ' || *tracer_pid == '\t') {
41 ++tracer_pid;
42 }
43 return *tracer_pid != '0' && *tracer_pid != '\n' && *tracer_pid != '\0';
44}
45
46static inline void v__gc_register_main_data_roots_linux(void) {
47 if (!v__gc_can_register_main_data_roots_linux()) {
48 return;
49 }
50 void* data_start_ptr = __data_start != NULL ? (void*)__data_start : (void*)data_start;
51 GC_add_roots(data_start_ptr, (void*)_end);
52}
53#endif
54
55#endif
56