-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcoredeps.c
197 lines (164 loc) · 5.28 KB
/
coredeps.c
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
// Default implementation of the Gera core dependencies using libc.
// To support a target that does not support the C standard library,
// reimplement this set of functions.
// Consider also changing the definition of 'GERACORE_MUTEX'
// inside of 'geracoredeps.h'.
#include "geracoredeps.h"
#include "gera.h"
#include <stdlib.h>
void* geracoredeps_malloc(size_t size) {
return malloc(size);
}
void* geracoredeps_realloc(void* ptr, size_t size) {
return realloc(ptr, size);
}
void geracoredeps_free(void* ptr) {
free(ptr);
}
#ifdef _WIN32
GERACORE_MUTEX geracoredeps_create_mutex() {
GERACORE_MUTEX m;
InitializeCriticalSection(&m);
return m;
}
void geracoredeps_lock_mutex(GERACORE_MUTEX* m) {
EnterCriticalSection(m);
}
void geracoredeps_unlock_mutex(GERACORE_MUTEX* m) {
LeaveCriticalSection(m);
}
void geracoredeps_free_mutex(GERACORE_MUTEX* m) {
DeleteCriticalSection(m);
}
#else
GERACORE_MUTEX geracoredeps_create_mutex() {
GERACORE_MUTEX m;
if(pthread_mutex_init(&m, NULL) != 0) {
gera___panic("Unable to create a mutex!");
}
return m;
}
void geracoredeps_lock_mutex(GERACORE_MUTEX* m) {
if(pthread_mutex_lock(m) != 0) {
gera___panic("Unable to lock a mutex!");
}
}
void geracoredeps_unlock_mutex(GERACORE_MUTEX* m) {
if(pthread_mutex_unlock(m) != 0) {
gera___panic("Unable to unlock a mutex!");
}
}
void geracoredeps_free_mutex(GERACORE_MUTEX* m) {
if(pthread_mutex_destroy(m) != 0) {
gera___panic("Unable to destroy a mutex!");
}
}
#endif
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <locale.h>
void geracoredeps_eprint(const char* text) {
size_t length = strlen(text);
fwrite(text, sizeof(char), length, stderr);
}
size_t geracoredeps_display_uint_length(size_t n) {
return snprintf(NULL, 0, "%zu", n);
}
void geracoredeps_display_uint(size_t n, char* buf) {
sprintf(buf, "%zu", n);
}
size_t geracoredeps_display_sint_length(gint n) {
return snprintf(NULL, 0, "%lld", (long long int) n);
}
void geracoredeps_display_sint(gint n, char* buf) {
sprintf(buf, "%lld", (long long int) n);
}
size_t geracoredeps_display_float_length(gfloat n) {
return snprintf(NULL, 0, "%f", n);
}
void geracoredeps_display_float(gfloat n, char* buf) {
sprintf(buf, "%f", n);
}
size_t geracoredeps_display_pointer_length(void* p) {
return snprintf(NULL, 0, "%p", p);
}
void geracoredeps_display_pointer(void* p, char* buf) {
sprintf(buf, "%p", p);
}
#ifdef _WIN32
#include <dbghelp.h>
void geracoredeps_eprint_backtrace() {
HANDLE process = GetCurrentProcess();
SymInitialize(process, NULL, TRUE);
void* trace_addresses[256];
WORD trace_size = CaptureStackBackTrace(
0, sizeof(trace_addresses) / sizeof(void*), trace_addresses, NULL
);
SYMBOL_INFO* symbol_info = calloc(
sizeof(SYMBOL_INFO) + 256 * sizeof(char), 1
);
symbol_info->MaxNameLen = 255;
symbol_info->SizeOfStruct = sizeof(SYMBOL_INFO);
fprintf(stderr, "Stack trace (latest call first):\n");
for(int call_i = 0; call_i < trace_size; call_i += 1) {
SymFromAddr(
process, (DWORD64)(trace_addresses[call_i]), 0, symbol_info
);
fprintf(
stderr,
" %d %s\n",
trace_size - call_i - 1,
symbol_info->Name
);
}
free(symbol_info);
}
#else
#include <execinfo.h>
#define ERROR_NOTE_COLOR "\033[0;90m"
#define ERROR_INDEX_COLOR "\033[0;90m"
#define ERROR_PROCEDURE_LOC_COLOR "\033[0;90m"
#define ERROR_PROCEDURE_COLOR "\033[0;1;32m"
#define ERROR_RESET_COLOR "\033[0m"
void geracoredeps_eprint_backtrace() {
void* trace_addresses[256];
int trace_size = backtrace(
trace_addresses, sizeof(trace_addresses) / sizeof(void*)
);
char** trace_symbols = backtrace_symbols(trace_addresses, trace_size);
if(trace_symbols == NULL) {
fprintf(
stderr,
ERROR_NOTE_COLOR "Stack trace unavailable." ERROR_RESET_COLOR
);
return;
}
fprintf(stderr, ERROR_NOTE_COLOR "Stack trace (latest call first):\n");
for(int call_i = 0; call_i < trace_size; call_i += 1) {
fprintf(
stderr,
ERROR_INDEX_COLOR " %d " ERROR_PROCEDURE_LOC_COLOR,
trace_size - call_i - 1
);
size_t name_len = strlen(trace_symbols[call_i]);
gbool in_parens = 0;
for(size_t ci = 0; ci < name_len; ci += 1) {
char c = trace_symbols[call_i][ci];
if(c == ')' || c == '+') {
fprintf(stderr, ERROR_PROCEDURE_LOC_COLOR);
}
fputc(c, stderr);
if(c == '(') {
fprintf(stderr, ERROR_PROCEDURE_COLOR);
}
}
fputc('\n', stderr);
}
fprintf(stderr, ERROR_RESET_COLOR);
free(trace_symbols);
}
#endif
void geracoredeps_exit(int code) {
exit(code);
}