forked from cory/tildefriends
		
	Minor error-sending cleanup. Produce callstacks.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4126 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		
							
								
								
									
										76
									
								
								src/ssb.c
									
									
									
									
									
								
							
							
						
						
									
										76
									
								
								src/ssb.c
									
									
									
									
									
								
							| @@ -25,6 +25,15 @@ | |||||||
| #include <time.h> | #include <time.h> | ||||||
| #include <uv.h> | #include <uv.h> | ||||||
|  |  | ||||||
|  | #include <backtrace.h> | ||||||
|  |  | ||||||
|  | #ifndef _WIN32 | ||||||
|  | #ifndef __ANDROID__ | ||||||
|  | #include <execinfo.h> | ||||||
|  | #endif | ||||||
|  | #include <unistd.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #if !defined(_countof) | #if !defined(_countof) | ||||||
| #define _countof(a) ((int)(sizeof((a)) / sizeof(*(a)))) | #define _countof(a) ((int)(sizeof((a)) / sizeof(*(a)))) | ||||||
| #endif | #endif | ||||||
| @@ -622,30 +631,68 @@ void tf_ssb_connection_rpc_send_json(tf_ssb_connection_t* connection, uint8_t fl | |||||||
| 	JS_FreeValue(context, json); | 	JS_FreeValue(context, json); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int _tf_ssb_backtrace_callback(void* data, uintptr_t pc, const char* filename, int line_number, const char* function) | ||||||
|  | { | ||||||
|  | 	char** stack = data; | ||||||
|  | 	char line[256]; | ||||||
|  | 	int length = snprintf(line, sizeof(line), "%p %s:%d %s\n", (void*)pc, filename, line_number, function); | ||||||
|  | 	int current = *stack ? strlen(*stack) : 0; | ||||||
|  | 	*stack = tf_resize_vec(*stack, current + length + 1); | ||||||
|  | 	memcpy(*stack + current, line, length + 1); | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void _tf_ssb_backtrace_error(void* data, const char* message, int error) | ||||||
|  | { | ||||||
|  | 	char** stack = data; | ||||||
|  | 	int length = strlen(message); | ||||||
|  | 	if (message) | ||||||
|  | 	{ | ||||||
|  | 		int current = *stack ? strlen(*stack) : 0; | ||||||
|  | 		*stack = tf_resize_vec(*stack, current + length + 1); | ||||||
|  | 		memcpy(*stack + current, message, length + 1); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static char* _tf_ssb_backtrace_string() | ||||||
|  | { | ||||||
|  | 	extern struct backtrace_state* g_backtrace_state; | ||||||
|  | 	int count = 0; | ||||||
|  | 	void* buffer[32]; | ||||||
|  | 	char* string = NULL; | ||||||
|  | #ifdef _WIN32 | ||||||
|  | 	count = CaptureStackBackTrace(0, sizeof(buffer) / sizeof(*buffer), buffer, NULL); | ||||||
|  | #elif !defined(__ANDROID__) | ||||||
|  | 	count = backtrace(buffer, sizeof(buffer) / sizeof(*buffer)); | ||||||
|  | #endif | ||||||
|  | 	for (int i = 0; i < count; i++) | ||||||
|  | 	{ | ||||||
|  | 		backtrace_pcinfo( | ||||||
|  | 			g_backtrace_state,  | ||||||
|  | 			(uintptr_t)buffer[i], | ||||||
|  | 			_tf_ssb_backtrace_callback, | ||||||
|  | 			_tf_ssb_backtrace_error, | ||||||
|  | 			&string); | ||||||
|  | 	} | ||||||
|  | 	return string; | ||||||
|  | } | ||||||
|  |  | ||||||
| void tf_ssb_connection_rpc_send_error(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const char* error) | void tf_ssb_connection_rpc_send_error(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, const char* error) | ||||||
| { | { | ||||||
| 	JSContext* context = connection->ssb->context; | 	JSContext* context = connection->ssb->context; | ||||||
| 	JSValue message = JS_NewObject(context); | 	JSValue message = JS_NewObject(context); | ||||||
|  | 	char* stack = _tf_ssb_backtrace_string(); | ||||||
| 	JS_SetPropertyStr(context, message, "name", JS_NewString(context, "Error")); | 	JS_SetPropertyStr(context, message, "name", JS_NewString(context, "Error")); | ||||||
| 	JS_SetPropertyStr(context, message, "stack", JS_NewString(context, "none")); | 	JS_SetPropertyStr(context, message, "stack", JS_NewString(context, stack)); | ||||||
| 	JS_SetPropertyStr(context, message, "message", JS_NewString(context, error)); | 	JS_SetPropertyStr(context, message, "message", JS_NewString(context, error)); | ||||||
| 	tf_ssb_connection_rpc_send_json(connection, flags | k_ssb_rpc_flag_end_error, request_number, message, NULL, NULL, NULL); | 	tf_ssb_connection_rpc_send_json(connection, ((flags & k_ssb_rpc_flag_stream) ? (k_ssb_rpc_flag_stream | k_ssb_rpc_flag_end_error) : 0), request_number, message, NULL, NULL, NULL); | ||||||
| 	JS_FreeValue(context, message); | 	JS_FreeValue(context, message); | ||||||
|  | 	tf_free(stack); | ||||||
| } | } | ||||||
|  |  | ||||||
| void tf_ssb_connection_rpc_send_error_method_not_allowed(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number) | void tf_ssb_connection_rpc_send_error_method_not_allowed(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number) | ||||||
| { | { | ||||||
| 	const char* k_unsupported = "{\"message\": \"method: is not in list of allowed methods\", \"name\": \"Error\", \"stack\": \"none\"}"; | 	tf_ssb_connection_rpc_send_error(connection, flags, request_number, "method is not in list of allowed methods"); | ||||||
| 	tf_ssb_connection_rpc_send( |  | ||||||
| 		connection, |  | ||||||
| 		k_ssb_rpc_flag_json | |  | ||||||
| 			((flags & k_ssb_rpc_flag_stream) ? (k_ssb_rpc_flag_stream | k_ssb_rpc_flag_end_error) : 0), |  | ||||||
| 		request_number, |  | ||||||
| 		(const uint8_t*)k_unsupported, |  | ||||||
| 		strlen(k_unsupported), |  | ||||||
| 		NULL, |  | ||||||
| 		NULL, |  | ||||||
| 		NULL); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| static int _utf8_len(uint8_t ch) | static int _utf8_len(uint8_t ch) | ||||||
| @@ -1378,8 +1425,7 @@ static void _tf_ssb_connection_rpc_recv(tf_ssb_connection_t* connection, uint8_t | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (request_number < 0 && | 	if (flags & k_ssb_rpc_flag_end_error) | ||||||
| 		(flags & k_ssb_rpc_flag_end_error)) |  | ||||||
| 	{ | 	{ | ||||||
| 		_tf_ssb_connection_remove_request(connection, -request_number); | 		_tf_ssb_connection_remove_request(connection, -request_number); | ||||||
| 	} | 	} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user