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:
parent
0cbc1a650b
commit
73863f9418
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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user