forked from JuliaLang/julia
-
Notifications
You must be signed in to change notification settings - Fork 0
/
signal-handling.c
111 lines (94 loc) · 2.69 KB
/
signal-handling.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
// This file is a part of Julia. License is MIT: https://julialang.org/license
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include "julia.h"
#include "julia_internal.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <threading.h>
// Profiler control variables //
static volatile intptr_t *bt_data_prof = NULL;
static volatile size_t bt_size_max = 0;
static volatile size_t bt_size_cur = 0;
static volatile uint64_t nsecprof = 0;
static volatile int running = 0;
static const uint64_t GIGA = 1000000000ULL;
// Timers to take samples at intervals
JL_DLLEXPORT void jl_profile_stop_timer(void);
JL_DLLEXPORT int jl_profile_start_timer(void);
volatile sig_atomic_t jl_signal_pending = 0;
volatile sig_atomic_t jl_defer_signal = 0;
int exit_on_sigint = 0;
JL_DLLEXPORT void jl_exit_on_sigint(int on) {exit_on_sigint = on;}
// what to do on SIGINT
JL_DLLEXPORT void jl_sigint_action(void)
{
if (exit_on_sigint) jl_exit(130); // 128+SIGINT
jl_throw(jl_interrupt_exception);
}
#if defined(_WIN32)
#include "signals-win.c"
#else
#include "signals-unix.c"
#endif
// what to do on a critical error
void jl_critical_error(int sig, bt_context_t context, intptr_t *bt_data, size_t *bt_size)
{
// This function is not allowed to reference any TLS variables.
// We need to explicitly pass in the TLS buffer pointer when
// we make `jl_filename` and `jl_lineno` thread local.
size_t n = *bt_size;
if (sig)
jl_safe_printf("\nsignal (%d): %s\n", sig, strsignal(sig));
jl_safe_printf("while loading %s, in expression starting on line %d\n", jl_filename, jl_lineno);
if (context)
*bt_size = n = rec_backtrace_ctx(bt_data, JL_MAX_BT_SIZE, context);
for(size_t i=0; i < n; i++)
jl_gdblookup(bt_data[i]);
gc_debug_print_status();
gc_debug_critical_error();
}
///////////////////////
// Utility functions //
///////////////////////
JL_DLLEXPORT int jl_profile_init(size_t maxsize, uint64_t delay_nsec)
{
bt_size_max = maxsize;
nsecprof = delay_nsec;
if (bt_data_prof != NULL)
free((void*)bt_data_prof);
bt_data_prof = (intptr_t*) calloc(maxsize, sizeof(intptr_t));
if (bt_data_prof == NULL && maxsize > 0)
return -1;
bt_size_cur = 0;
return 0;
}
JL_DLLEXPORT uint8_t *jl_profile_get_data(void)
{
return (uint8_t*) bt_data_prof;
}
JL_DLLEXPORT size_t jl_profile_len_data(void)
{
return bt_size_cur;
}
JL_DLLEXPORT size_t jl_profile_maxlen_data(void)
{
return bt_size_max;
}
JL_DLLEXPORT uint64_t jl_profile_delay_nsec(void)
{
return nsecprof;
}
JL_DLLEXPORT void jl_profile_clear_data(void)
{
bt_size_cur = 0;
}
JL_DLLEXPORT int jl_profile_is_running(void)
{
return running;
}
#ifdef __cplusplus
}
#endif