pstrace

Форк
0
/
main.c 
192 строки · 4.3 Кб
1
//system
2
#include <stdlib.h>
3
#include <fcntl.h>
4
#include <stdint.h>
5
#include <stdio.h>
6

7
#include "../include/libpst.h"
8

9
typedef enum {
10
	DEF_1 = 1,
11
	DEF_2,
12
	DEF_3
13
} my_int;
14

15
void Fun2(int arg1, uint32_t arg2, int* ptr)
16
{
17
	*ptr = arg1;
18
	void* ptr2 = ptr+1;
19
	printf("%p\n", ptr2);
20
}
21

22
uint32_t Fun1(const int arg1, my_int arg2, uint32_t arg3)
23
{
24
	int my_local = arg1 + 2;
25
	printf("%d\n", my_local);
26
	Fun2(my_local, arg3, (int*)0x12345);
27
	return arg2;
28
}
29

30
#include <ucontext.h>
31
#include <execinfo.h>
32
#include <signal.h>
33
#include <limits.h>
34
#include <sys/types.h>
35
#include <sys/stat.h>
36
#include <fcntl.h>
37
#include <string.h>
38

39
typedef void (*sig_handler_t)(int sig);
40

41
void SetSignalHandler(sig_handler_t handler);
42

43
void SigusrHandler(int sig)
44
{
45
    // just do nothing on SIGUSR1 & SIGUSR2
46
    SetSignalHandler(SigusrHandler);
47
}
48

49
volatile sig_atomic_t fatal_error_in_progress = 0;
50

51
void FatalSignalHandler(int sig, siginfo_t* info, void* context)
52
{
53
	// Since this handler is established for more than one kind of signal,
54
	// it might still get invoked recursively by delivery of some other kind
55
	// of signal.  Use a static variable to keep track of that.
56
    if (fatal_error_in_progress) {
57
	    raise (sig);
58
    }
59

60
    fatal_error_in_progress = 1;
61

62
    printf("%s signal handled\n", strsignal(sig));
63
	if((context != 0) && (sig == SIGSEGV || sig == SIGABRT || sig == SIGBUS || sig == SIGFPE))
64
	{
65
	    pst_handler* handler = pst_lib_init((ucontext_t*)context, NULL, 0);
66
	    if(!handler) {
67
	        printf("Failed to allocate pst handler\n");
68
	        return;
69
	    }
70

71
	    if(pst_unwind_simple(handler)) {
72
	        printf("Simple unwind-based stack trace:\n");
73
            printf("--------------------------------\n");
74
	        printf("%s\n", pst_print_simple(handler));
75
	        if(pst_unwind_pretty(handler)) {
76
	            printf("DWARF-based stack trace information:\n");
77
	            printf("------------------------------------\n");
78
	            printf("%s", pst_print_pretty(handler));
79
	        } else {
80
	            printf("Failed to use DWARF for unwind stack trace\n");
81
	        }
82
	    } else {
83
	        printf("No stack trace obtained\n");
84
	    }
85

86
	    pst_lib_fini(handler);
87
    }
88

89

90
    // comment out line below to prevent coredump
91
    // exit(EXIT_FAILURE);
92

93
	// Now reraise the signal.
94
	// We reactivate the signal’s default handling, which is to terminate the process.
95
	// We could just call exit or abort, but reraising the signal sets the return status
96
	// from the process correctly.
97
	signal (sig, SIG_DFL);
98
	raise (sig);
99
}
100

101
void SignalHandler(int sig)
102
{
103
    // do nothing and reset to our handler back
104
	SetSignalHandler(0);
105
}
106

107
#include <sys/time.h>
108
#include <sys/resource.h>
109

110
void SetSignalHandler(sig_handler_t handler)
111
{
112
	//signals set
113
	sigset_t ss;
114
	sigfillset(&ss);
115

116
	//remove previous handlers
117
	sigdelset(&ss, SIGUSR1);
118
	sigdelset(&ss, SIGUSR2);
119
	sigdelset(&ss, SIGSEGV);
120
	sigdelset(&ss, SIGABRT);
121
	sigdelset(&ss, SIGBUS);
122
	sigdelset(&ss, SIGFPE);
123
	sigdelset(&ss, SIGCHLD);
124
	sigdelset(&ss, SIGTERM);		//without replacement
125

126
	//signal action
127
	struct sigaction sa;
128
	sa.sa_flags = SA_SIGINFO;
129
	sa.sa_mask = ss;
130

131
	// cleanup
132
	sa.sa_handler = NULL;
133
	sa.sa_sigaction = NULL;
134

135
	//set stop signal
136
	sa.sa_handler = (handler == NULL) ? SignalHandler : handler;
137
	sigaction(SIGUSR1, &sa, 0);
138

139
	sa.sa_handler = SignalHandler;
140
	sigaction(SIGUSR2, &sa, 0);
141

142
	// cleanup
143
	sa.sa_handler = NULL;
144
	sa.sa_sigaction = NULL;
145

146
	//set SIGSEGV
147
	sa.sa_sigaction = FatalSignalHandler;
148
	sigaction(SIGSEGV, &sa, 0);
149

150
	//set SIGABRT
151
	sa.sa_sigaction = FatalSignalHandler;
152
	sigaction(SIGABRT, &sa, 0);
153

154
	//set SIGBUS
155
	sa.sa_sigaction = FatalSignalHandler;
156
	sigaction(SIGBUS, &sa, 0);
157

158
	//set FPE signal
159
	sa.sa_sigaction = FatalSignalHandler;
160
	sigaction(SIGFPE, &sa, 0);
161

162
	//enable signals set
163
	sigprocmask(SIG_BLOCK, &ss, 0);
164

165
	//set core dump size to 1Gb
166
	struct rlimit limit;
167
	limit.rlim_cur = 1073741824;
168
	limit.rlim_max = 1073741824;
169
	if (setrlimit(RLIMIT_CORE, &limit))
170
	{
171
		printf("Failed to set limit for core dump file size\n");
172
	}
173
}
174

175
void ResetSignalHandler() {
176
	signal(SIGINT, SIG_DFL);
177
	signal(SIGABRT, SIG_DFL);
178
    signal(SIGTERM, SIG_DFL);
179
    signal(SIGSEGV, SIG_DFL);
180
    signal(SIGUSR1, SIG_DFL);
181
    signal(SIGUSR2, SIG_DFL);
182
    signal(SIGCHLD, SIG_DFL);
183
}
184

185
int main(int argc, char* argv[])
186
{
187
    SetSignalHandler(SigusrHandler);
188

189
    Fun1(1, DEF_2, 5);
190

191
    return 0;
192
}
193

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.