diff --git a/core/buffer.c b/core/buffer.c index e05a66b2..d258ac02 100644 --- a/core/buffer.c +++ b/core/buffer.c @@ -220,6 +220,17 @@ int uwsgi_buffer_append_keynum(struct uwsgi_buffer *ub, char *key, uint16_t keyl return uwsgi_buffer_append(ub, buf, ret); } +int uwsgi_buffer_append_valnum(struct uwsgi_buffer *ub, int64_t num) { + char buf[sizeof(UMAX64_STR)+1]; + int ret = snprintf(buf, (sizeof(UMAX64_STR)+1), "%lld", (long long) num); + if (ret <= 0 || ret > (int) (sizeof(UMAX64_STR)+1)) { + return -1; + } + if (uwsgi_buffer_u16le(ub, ret)) return -1; + return uwsgi_buffer_append(ub, buf, ret); +} + + int uwsgi_buffer_append_keyipv4(struct uwsgi_buffer *ub, char *key, uint16_t keylen, void *addr) { if (uwsgi_buffer_u16le(ub, keylen)) return -1; if (uwsgi_buffer_append(ub, key, keylen)) return -1; diff --git a/core/exceptions.c b/core/exceptions.c index af7752f0..a1cf7efc 100644 --- a/core/exceptions.c +++ b/core/exceptions.c @@ -52,6 +52,55 @@ static void append_vars_to_ubuf(char *key, uint16_t keylen, char *val, uint16_t if (uwsgi_buffer_append(ub, "\n", 1)) return; } +static void append_backtrace_to_ubuf(uint16_t pos, char *value, uint16_t len, void *data) { + struct uwsgi_buffer *ub = (struct uwsgi_buffer *) data; + + uint16_t item = 0; + if (pos > 0) { + item = pos % 5; + } + + switch(item) { + // filename + case 0: + if (uwsgi_buffer_append(ub, "filename: \"", 11)) return; + if (uwsgi_buffer_append(ub, value, len)) return; + if (uwsgi_buffer_append(ub, "\" ", 2)) return; + break; + // lineno + case 1: + if (uwsgi_buffer_append(ub, "line: ", 6)) return; + if (uwsgi_buffer_append(ub, value, len)) return; + if (uwsgi_buffer_append(ub, " ", 1)) return; + break; + // function + case 2: + if (uwsgi_buffer_append(ub, "function: \"", 11)) return; + if (uwsgi_buffer_append(ub, value, len)) return; + if (uwsgi_buffer_append(ub, "\" ", 2)) return; + break; + // text + case 3: + if (uwsgi_buffer_append(ub, "text/code: \"", 12)) return; + if (uwsgi_buffer_append(ub, value, len)) return; + if (uwsgi_buffer_append(ub, "\" ", 2)) return; + break; + // custom + case 4: + if (len > 0) { + if (uwsgi_buffer_append(ub, "custom: \"", 9)) return; + if (uwsgi_buffer_append(ub, value, len)) return; + if (uwsgi_buffer_append(ub, "\" ", 2)) return; + } + if (uwsgi_buffer_append(ub, "\n", 1)) return; + break; + default: + break; + } + +} + + int uwsgi_exceptions_catch(struct wsgi_request *wsgi_req) { if (uwsgi_response_prepare_headers(wsgi_req, "500 Internal Server Error", 25)) { @@ -135,6 +184,35 @@ notavail2: if (uwsgi_buffer_append(ub, "\n\n", 2)) goto error; + if (uwsgi_buffer_append(ub, "Backtrace:\n", 11)) goto error; + + if (uwsgi.p[wsgi_req->uh->modifier1]->backtrace) { + struct uwsgi_buffer *ub_exc_bt = uwsgi.p[wsgi_req->uh->modifier1]->backtrace(wsgi_req); + if (ub_exc_bt) { + struct uwsgi_buffer *parsed_bt = uwsgi_buffer_new(4096); + if (uwsgi_hooked_parse_array(ub_exc_bt->buf, ub_exc_bt->pos, append_backtrace_to_ubuf, parsed_bt)) { + uwsgi_buffer_destroy(ub_exc_bt); + uwsgi_buffer_destroy(parsed_bt); + goto error; + } + uwsgi_buffer_destroy(ub_exc_bt); + if (uwsgi_buffer_append(ub, parsed_bt->buf, parsed_bt->pos)) { + uwsgi_buffer_destroy(parsed_bt); + goto error; + } + uwsgi_buffer_destroy(parsed_bt); + } + else { + goto notavail4; + } + } + else { +notavail4: + if (uwsgi_buffer_append(ub, "-Not available-", 15)) goto error; + } + + if (uwsgi_buffer_append(ub, "\n\n", 2)) goto error; + if (uwsgi_hooked_parse(wsgi_req->buffer, wsgi_req->uh->pktsize, append_vars_to_ubuf, ub)) { goto error; } @@ -151,3 +229,82 @@ error: return -1; } + +void uwsgi_manage_exception(struct wsgi_request *wsgi_req,int catch) { + + int do_exit = 0; + + uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].exceptions++; + uwsgi_apps[wsgi_req->app_id].exceptions++; + + if (uwsgi.reload_on_exception) { + do_exit = 1; + goto check_catch; + } + + if (uwsgi.reload_on_exception_type && uwsgi.p[wsgi_req->uh->modifier1]->exception_class) { + struct uwsgi_buffer *ub = uwsgi.p[wsgi_req->uh->modifier1]->exception_msg(wsgi_req); + if (ub) { + struct uwsgi_string_list *usl = uwsgi.reload_on_exception_type; + while (usl) { + if (!uwsgi_strncmp(usl->value, usl->len, ub->buf, ub->len)) { + do_exit = 1; + uwsgi_buffer_destroy(ub); + goto check_catch; + } + usl = usl->next; + } + uwsgi_buffer_destroy(ub); + } + } + + if (uwsgi.reload_on_exception_value && uwsgi.p[wsgi_req->uh->modifier1]->exception_msg) { + struct uwsgi_buffer *ub = uwsgi.p[wsgi_req->uh->modifier1]->exception_msg(wsgi_req); + if (ub) { + struct uwsgi_string_list *usl = uwsgi.reload_on_exception_value; + while (usl) { + if (!uwsgi_strncmp(usl->value, usl->len, ub->buf, ub->len)) { + do_exit = 1; + uwsgi_buffer_destroy(ub); + goto check_catch; + } + usl = usl->next; + } + uwsgi_buffer_destroy(ub); + } + } + + if (uwsgi.reload_on_exception_repr && uwsgi.p[wsgi_req->uh->modifier1]->exception_repr) { + struct uwsgi_buffer *ub = uwsgi.p[wsgi_req->uh->modifier1]->exception_msg(wsgi_req); + if (ub) { + struct uwsgi_string_list *usl = uwsgi.reload_on_exception_repr; + while (usl) { + if (!uwsgi_strncmp(usl->value, usl->len, ub->buf, ub->len)) { + do_exit = 1; + uwsgi_buffer_destroy(ub); + goto check_catch; + } + usl = usl->next; + } + uwsgi_buffer_destroy(ub); + } + } + +check_catch: + if (catch) { + if (uwsgi_exceptions_catch(wsgi_req)) { + // for now, just goto, new features could be added + goto log; + } + } + +log: + if (uwsgi.p[wsgi_req->uh->modifier1]->exception_log) { + uwsgi.p[wsgi_req->uh->modifier1]->exception_log(wsgi_req); + } + + if (do_exit) { + exit(UWSGI_EXCEPTION_CODE); + } + +} diff --git a/core/master_utils.c b/core/master_utils.c index d637cbc2..bf5cba66 100644 --- a/core/master_utils.c +++ b/core/master_utils.c @@ -5,6 +5,16 @@ extern struct uwsgi_server uwsgi; void worker_wakeup() { } +uint64_t uwsgi_worker_exceptions(int wid) { + uint64_t total = 0; + int i; + for(i=0;i bufferend) + return -1; + memcpy(&valsize, ptrbuf, 2); +#ifdef __BIG_ENDIAN__ + valsize = uwsgi_swap16(valsize); +#endif + ptrbuf += 2; + if (ptrbuf + valsize > bufferend) + return -1; + + // key + value = ptrbuf; + // now call the hook + hook(pos, value, valsize, data); + ptrbuf += valsize; + pos++; + } + + return 0; + +} + + int uwsgi_hooked_parse_dict_dgram(int fd, char *buffer, size_t len, uint8_t modifier1, uint8_t modifier2, void (*hook) (char *, uint16_t, char *, uint16_t, void *), void *data) { struct uwsgi_header *uh; diff --git a/core/utils.c b/core/utils.c index 18c15cc2..d55bedde 100644 --- a/core/utils.c +++ b/core/utils.c @@ -3120,49 +3120,6 @@ void uwsgi_write_pidfile(char *pidfile_name) { fclose(pidfile); } -int uwsgi_manage_exception(char *type, char *value, char *repr) { - - struct uwsgi_string_list *list = NULL; - - // first manage non fatal case (like signals and alarm).... - - if (uwsgi.reload_on_exception) { - return -1; - } - - if (type) { - list = uwsgi.reload_on_exception_type; - while (list) { - if (!strcmp(list->value, type)) { - return -1; - } - list = list->next; - } - } - - if (value) { - list = uwsgi.reload_on_exception_value; - while (list) { - if (!strcmp(list->value, value)) { - return -1; - } - list = list->next; - } - } - - if (repr) { - list = uwsgi.reload_on_exception_repr; - while (list) { - if (!strcmp(list->value, repr)) { - return -1; - } - list = list->next; - } - } - - return 0; -} - char *uwsgi_expand_path(char *dir, int dir_len, char *ptr) { char src[PATH_MAX + 1]; memcpy(src, dir, dir_len); diff --git a/plugins/python/pump_subhandler.c b/plugins/python/pump_subhandler.c index 4e237d74..0e4f026f 100644 --- a/plugins/python/pump_subhandler.c +++ b/plugins/python/pump_subhandler.c @@ -271,7 +271,9 @@ int uwsgi_response_subhandler_pump(struct wsgi_request *wsgi_req) { pychunk = PyIter_Next(wsgi_req->async_placeholder); if (!pychunk) { - if (PyErr_Occurred()) PyErr_Print(); + if (PyErr_Occurred()) { + uwsgi_manage_exception(wsgi_req, uwsgi.catch_exceptions); + } goto clear; } diff --git a/plugins/python/python_plugin.c b/plugins/python/python_plugin.c index 1b85d3d7..e7c2d863 100644 --- a/plugins/python/python_plugin.c +++ b/plugins/python/python_plugin.c @@ -822,11 +822,6 @@ void init_uwsgi_embedded_module() { exit(1); } - if (PyDict_SetItemString(up.embedded_dict, "message_manager_marshal", Py_None)) { - PyErr_Print(); - exit(1); - } - init_uwsgi_module_advanced(new_uwsgi_module); if (uwsgi.spoolers) { @@ -1879,6 +1874,7 @@ struct uwsgi_plugin pypy_plugin = { .exception_msg = uwsgi_python_exception_msg, .exception_repr = uwsgi_python_exception_repr, .exception_log = uwsgi_python_exception_log, + .backtrace = uwsgi_python_backtrace, }; diff --git a/plugins/python/pyutils.c b/plugins/python/pyutils.c index 42a7d036..b258931e 100644 --- a/plugins/python/pyutils.c +++ b/plugins/python/pyutils.c @@ -41,56 +41,80 @@ char *uwsgi_python_get_exception_type(PyObject *exc) { return NULL; } -char *uwsgi_python_get_exception_value(PyObject *value) { - return PyString_AsString( PyObject_Str(value) ); -} - -char *uwsgi_python_get_exception_repr(PyObject *exc, PyObject *value) { - char *exc_type = uwsgi_python_get_exception_type(exc); - char *exc_value = uwsgi_python_get_exception_value(value); - - if (exc_type && exc_value) { - return uwsgi_concat3(exc_type, ": ", exc_value); - } - - return NULL; -} - -int uwsgi_python_manage_exceptions(void) { +struct uwsgi_buffer *uwsgi_python_backtrace(struct wsgi_request *wsgi_req) { PyObject *type = NULL; - PyObject *value = NULL; - PyObject *traceback = NULL; - - char *exc_type = NULL; - char *exc_value = NULL; - char *exc_repr = NULL; + PyObject *value = NULL; + PyObject *traceback = NULL; + struct uwsgi_buffer *ub = NULL; PyErr_Fetch(&type, &value, &traceback); - PyErr_NormalizeException(&type, &value, &traceback); + PyErr_NormalizeException(&type, &value, &traceback); - if (uwsgi.reload_on_exception_type) { - exc_type = uwsgi_python_get_exception_type(type); + // traceback could not be available + if (!traceback) goto end; + + PyObject *traceback_module = PyImport_ImportModule("traceback"); + if (!traceback_module) { + goto end; } - if (uwsgi.reload_on_exception_value) { - exc_value = uwsgi_python_get_exception_value(value); + PyObject *traceback_dict = PyModule_GetDict(traceback_module); + PyObject *extract_tb = PyDict_GetItemString(traceback_dict, "extract_tb"); + if (!extract_tb) goto end; + PyObject *args = PyTuple_New(1); + Py_INCREF(traceback); + PyTuple_SetItem(args, 0, traceback); + PyObject *result = PyEval_CallObject(extract_tb, args); + Py_DECREF(args); + + if (!result) goto end; + + ub = uwsgi_buffer_new(4096); + Py_ssize_t i; + // we have to build a uwsgi array with 5 items (4 are taken from the python tb) + for(i=0;i< PyList_Size(result);i++) { + PyObject *t = PyList_GetItem(result, i); + PyObject *tb_filename = PyTuple_GetItem(t, 0); + PyObject *tb_lineno = PyTuple_GetItem(t, 1); + PyObject *tb_function = PyTuple_GetItem(t, 2); + PyObject *tb_text = PyTuple_GetItem(t, 3); + + int64_t line_no = PyInt_AsLong(tb_lineno); + + // filename + if (uwsgi_buffer_u16le(ub, PyString_Size(tb_filename))) goto end0; + if (uwsgi_buffer_append(ub, PyString_AsString(tb_filename), PyString_Size(tb_filename))) goto end0; + + // lineno + if (uwsgi_buffer_append_valnum(ub, line_no)) goto end0; + + // function + if (uwsgi_buffer_u16le(ub, PyString_Size(tb_function))) goto end0; + if (uwsgi_buffer_append(ub, PyString_AsString(tb_function), PyString_Size(tb_function))) goto end0; + + // text + if (uwsgi_buffer_u16le(ub, PyString_Size(tb_text))) goto end0; + if (uwsgi_buffer_append(ub, PyString_AsString(tb_text), PyString_Size(tb_text))) goto end0; + + // custom (unused) + if (uwsgi_buffer_u16le(ub, 0)) goto end0; + if (uwsgi_buffer_append(ub, "", 0)) goto end0; + } - if (uwsgi.reload_on_exception_repr) { - exc_repr = uwsgi_python_get_exception_repr(type, value); - } + Py_DECREF(result); + goto end; - int ret = uwsgi_manage_exception(exc_type, exc_value, exc_repr); - - // free memory allocated for strcmp - if (exc_type) free(exc_type); - if (exc_repr) free(exc_repr); - - PyErr_Restore(type, value, traceback); - - return ret; +end0: + Py_DECREF(result); + uwsgi_buffer_destroy(ub); + ub = NULL; +end: + PyErr_Restore(type, value, traceback); + return ub; } + struct uwsgi_buffer *uwsgi_python_exception_class(struct wsgi_request *wsgi_req) { PyObject *type = NULL; PyObject *value = NULL; @@ -111,6 +135,7 @@ struct uwsgi_buffer *uwsgi_python_exception_class(struct wsgi_request *wsgi_req) } } end: + free(class); PyErr_Restore(type, value, traceback); return ub; } @@ -183,28 +208,7 @@ PyObject *python_call(PyObject *callable, PyObject *args, int catch, struct wsgi //uwsgi_log("called\n"); if (PyErr_Occurred()) { - - - int do_exit = uwsgi_python_manage_exceptions(); - - if (PyErr_ExceptionMatches(PyExc_MemoryError)) { - uwsgi_log("Memory Error detected !!!\n"); - } - - // this can be in a spooler or in the master - if (uwsgi.mywid > 0) { - uwsgi.workers[uwsgi.mywid].exceptions++; - if (wsgi_req) { - uwsgi_apps[wsgi_req->app_id].exceptions++; - } - } - if (!catch) { - PyErr_Print(); - } - - if (do_exit) { - exit(UWSGI_EXCEPTION_CODE); - } + uwsgi_manage_exception(wsgi_req, catch); } #ifdef UWSGI_DEBUG diff --git a/plugins/python/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c index a98bb242..aaf331c3 100644 --- a/plugins/python/uwsgi_pymodule.c +++ b/plugins/python/uwsgi_pymodule.c @@ -1898,58 +1898,6 @@ PyObject *py_uwsgi_async_connect(PyObject * self, PyObject * args) { return PyInt_FromLong(uwsgi_connect(socket_name, 0, 1)); } -PyObject *py_uwsgi_async_send_message(PyObject * self, PyObject * args) { - - PyObject *pyobj = NULL; - - int uwsgi_fd; - int modifier1 = 0; - int modifier2 = 0; - - char *encoded; - uint16_t esize = 0; - - if (!PyArg_ParseTuple(args, "iiiO:async_send_message", &uwsgi_fd, &modifier1, &modifier2, &pyobj)) { - return NULL; - } - - if (uwsgi_fd < 0) - goto clear; - - // now check for the type of object to send (fallback to marshal) - if (PyDict_Check(pyobj)) { - encoded = uwsgi_encode_pydict(pyobj, &esize); - if (esize > 0) { - UWSGI_RELEASE_GIL uwsgi_send_message(uwsgi_fd, (uint8_t) modifier1, (uint8_t) modifier2, encoded, esize, -1, 0, 0); - free(encoded); - } - } - else if (PyString_Check(pyobj)) { - encoded = PyString_AsString(pyobj); - esize = PyString_Size(pyobj); - UWSGI_RELEASE_GIL uwsgi_send_message(uwsgi_fd, (uint8_t) modifier1, (uint8_t) modifier2, encoded, esize, -1, 0, 0); - } -#ifndef UWSGI_PYPY - else { - PyObject *marshalled = PyMarshal_WriteObjectToString(pyobj, 1); - if (!marshalled) { - PyErr_Print(); - goto clear; - } - - encoded = PyString_AsString(marshalled); - esize = PyString_Size(marshalled); - UWSGI_RELEASE_GIL uwsgi_send_message(uwsgi_fd, (uint8_t) modifier1, (uint8_t) modifier2, encoded, esize, -1, 0, 0); - } -#endif - - UWSGI_GET_GIL clear: - - Py_INCREF(Py_None); - return Py_None; - -} - /* uWSGI masterpid */ PyObject *py_uwsgi_masterpid(PyObject * self, PyObject * args) { if (uwsgi.master_process) { @@ -2014,7 +1962,7 @@ PyObject *py_uwsgi_workers(PyObject * self, PyObject * args) { } Py_DECREF(zero); - zero = PyLong_FromUnsignedLongLong(uwsgi.workers[i + 1].exceptions); + zero = PyLong_FromUnsignedLongLong(uwsgi_worker_exceptions(i+1)); if (PyDict_SetItemString(worker_dict, "exceptions", zero)) { goto clear; } @@ -2504,7 +2452,6 @@ static PyMethodDef uwsgi_advanced_methods[] = { #endif {"async_sleep", py_uwsgi_async_sleep, METH_VARARGS, ""}, {"async_connect", py_uwsgi_async_connect, METH_VARARGS, ""}, - {"async_send_message", py_uwsgi_async_send_message, METH_VARARGS, ""}, {"green_schedule", py_uwsgi_suspend, METH_VARARGS, ""}, {"suspend", py_uwsgi_suspend, METH_VARARGS, ""}, diff --git a/plugins/python/uwsgi_python.h b/plugins/python/uwsgi_python.h index f76807a6..0fe8e1b6 100644 --- a/plugins/python/uwsgi_python.h +++ b/plugins/python/uwsgi_python.h @@ -34,7 +34,7 @@ #endif #define uwsgi_py_write_set_exception(x) if (!uwsgi.disable_write_exception) { PyErr_SetString(PyExc_IOError, "write error"); }; -#define uwsgi_py_write_exception(x) uwsgi_py_write_set_exception(x); PyErr_Print(); +#define uwsgi_py_write_exception(x) uwsgi_py_write_set_exception(x); uwsgi_manage_exception(x, 0); #define uwsgi_py_check_write_errors if (wsgi_req->write_errors > 0 && uwsgi.write_errors_exception_only) {\ @@ -258,7 +258,6 @@ char *uwsgi_pythonize(char *); void *uwsgi_python_autoreloader_thread(void *); void *uwsgi_python_tracebacker_thread(void *); -int uwsgi_python_manage_exceptions(void); int uwsgi_python_do_send_headers(struct wsgi_request *); void *uwsgi_python_tracebacker_thread(void *); PyObject *uwsgi_python_setup_thread(char *); @@ -266,6 +265,7 @@ PyObject *uwsgi_python_setup_thread(char *); struct uwsgi_buffer *uwsgi_python_exception_class(struct wsgi_request *); struct uwsgi_buffer *uwsgi_python_exception_msg(struct wsgi_request *); struct uwsgi_buffer *uwsgi_python_exception_repr(struct wsgi_request *); +struct uwsgi_buffer *uwsgi_python_backtrace(struct wsgi_request *); void uwsgi_python_exception_log(struct wsgi_request *); #ifdef UWSGI_PYPY diff --git a/plugins/python/web3_subhandler.c b/plugins/python/web3_subhandler.c index 1763990f..2009ada9 100644 --- a/plugins/python/web3_subhandler.c +++ b/plugins/python/web3_subhandler.c @@ -178,7 +178,9 @@ int uwsgi_response_subhandler_web3(struct wsgi_request *wsgi_req) { pychunk = PyIter_Next(wsgi_req->async_placeholder); if (!pychunk) { - if (PyErr_Occurred()) PyErr_Print(); + if (PyErr_Occurred()) { + uwsgi_manage_exception(wsgi_req, uwsgi.catch_exceptions); + } goto clear; } diff --git a/plugins/python/wsgi_handlers.c b/plugins/python/wsgi_handlers.c index 19584fcf..aa1e65ba 100644 --- a/plugins/python/wsgi_handlers.c +++ b/plugins/python/wsgi_handlers.c @@ -378,11 +378,6 @@ int uwsgi_request_wsgi(struct wsgi_request *wsgi_req) { } - else if (uwsgi.catch_exceptions) { - uwsgi_exceptions_catch(wsgi_req); - PyErr_Print(); - } - // this object must be freed/cleared always end: if (wsgi_req->async_input) { @@ -413,7 +408,7 @@ void uwsgi_after_request_wsgi(struct wsgi_request *wsgi_req) { UWSGI_GET_GIL PyObject *arh = python_call(up.after_req_hook, up.after_req_hook_args, 0, NULL); if (!arh) { - PyErr_Print(); + uwsgi_manage_exception(wsgi_req, 0); } else { Py_DECREF(arh); diff --git a/plugins/python/wsgi_subhandler.c b/plugins/python/wsgi_subhandler.c index 60a34e17..303efca1 100644 --- a/plugins/python/wsgi_subhandler.c +++ b/plugins/python/wsgi_subhandler.c @@ -169,16 +169,7 @@ int uwsgi_response_subhandler_wsgi(struct wsgi_request *wsgi_req) { if (!pychunk) { exception: if (PyErr_Occurred()) { - int do_exit = uwsgi_python_manage_exceptions(); - if (PyErr_ExceptionMatches(PyExc_MemoryError)) { - uwsgi_log("Memory Error detected !!!\n"); - } - uwsgi.workers[uwsgi.mywid].exceptions++; - uwsgi_apps[wsgi_req->app_id].exceptions++; - PyErr_Print(); - if (do_exit) { - exit(UWSGI_EXCEPTION_CODE); - } + uwsgi_manage_exception(wsgi_req, uwsgi.catch_exceptions); } goto clear; } @@ -230,7 +221,7 @@ clear: #endif PyObject *close_method_output = PyEval_CallObject(close_method, close_method_args); if (PyErr_Occurred()) { - PyErr_Print(); + uwsgi_manage_exception(wsgi_req, 0); } Py_DECREF(close_method_args); Py_XDECREF(close_method_output); diff --git a/uwsgi.h b/uwsgi.h index 5d1b0f67..38076f39 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -2313,6 +2313,7 @@ struct uwsgi_rpc { uint64_t offloaded_requests; uint64_t write_errors; + uint64_t exceptions; pthread_t thread_id; @@ -2362,8 +2363,6 @@ struct uwsgi_rpc { int manage_next_request; - uint64_t exceptions; - int destroy; int apps_cnt; @@ -2621,8 +2620,9 @@ void async_add_timeout(struct wsgi_request *, int); #define uwsgi_waitfd(a, b) uwsgi_waitfd_event(a, b, POLLIN) #define uwsgi_waitfd_write(a, b) uwsgi_waitfd_event(a, b, POLLOUT) - int uwsgi_hooked_parse_dict_dgram(int, char *, size_t, uint8_t, uint8_t, void (*)(char *, uint16_t, char *, uint16_t, void *), void *); - int uwsgi_hooked_parse(char *, size_t, void (*)(char *, uint16_t, char *, uint16_t, void *), void *); +int uwsgi_hooked_parse_dict_dgram(int, char *, size_t, uint8_t, uint8_t, void (*)(char *, uint16_t, char *, uint16_t, void *), void *); +int uwsgi_hooked_parse(char *, size_t, void (*)(char *, uint16_t, char *, uint16_t, void *), void *); +int uwsgi_hooked_parse_array(char *, size_t, void (*) (uint16_t, char *, uint16_t, void *), void *); int uwsgi_get_dgram(int, struct wsgi_request *); @@ -3304,8 +3304,6 @@ socklen_t socket_to_in_addr6(char *, char *, int, struct sockaddr_in6 *); struct uwsgi_lock_item *uwsgi_lock_ipcsem_init(char *); void uwsgi_write_pidfile(char *); -int uwsgi_manage_exception(char *, char *, char *); -int uwsgi_exceptions_catch(struct wsgi_request *); void uwsgi_protected_close(int); ssize_t uwsgi_protected_read(int, void *, size_t); @@ -3527,32 +3525,33 @@ int uwsgi_exceptions_catch(struct wsgi_request *); void uwsgi_bind_sockets(void); void uwsgi_set_sockets_protocols(void); - struct uwsgi_buffer *uwsgi_buffer_new(size_t); - int uwsgi_buffer_append(struct uwsgi_buffer *, char *, size_t); - int uwsgi_buffer_fix(struct uwsgi_buffer *, size_t); - int uwsgi_buffer_ensure(struct uwsgi_buffer *, size_t); - void uwsgi_buffer_destroy(struct uwsgi_buffer *); - int uwsgi_buffer_u8(struct uwsgi_buffer *, uint8_t); - int uwsgi_buffer_byte(struct uwsgi_buffer *, char); - int uwsgi_buffer_u16le(struct uwsgi_buffer *, uint16_t); - int uwsgi_buffer_u16be(struct uwsgi_buffer *, uint16_t); - int uwsgi_buffer_u32be(struct uwsgi_buffer *, uint32_t); - int uwsgi_buffer_u32le(struct uwsgi_buffer *, uint32_t); - int uwsgi_buffer_u24be(struct uwsgi_buffer *, uint32_t); - int uwsgi_buffer_u64be(struct uwsgi_buffer *, uint64_t); - int uwsgi_buffer_num64(struct uwsgi_buffer *, int64_t); - int uwsgi_buffer_append_keyval(struct uwsgi_buffer *, char *, uint16_t, char *, uint16_t); - int uwsgi_buffer_append_keyval32(struct uwsgi_buffer *, char *, uint32_t, char *, uint32_t); - int uwsgi_buffer_append_keynum(struct uwsgi_buffer *, char *, uint16_t, int64_t); - int uwsgi_buffer_append_ipv4(struct uwsgi_buffer *, void *); - int uwsgi_buffer_append_keyipv4(struct uwsgi_buffer *, char *, uint16_t, void *); - int uwsgi_buffer_decapitate(struct uwsgi_buffer *, size_t); - int uwsgi_buffer_append_base64(struct uwsgi_buffer *, char *, size_t); - int uwsgi_buffer_insert(struct uwsgi_buffer *, size_t, char *, size_t); - int uwsgi_buffer_insert_chunked(struct uwsgi_buffer *, size_t, size_t); - int uwsgi_buffer_append_chunked(struct uwsgi_buffer *, size_t); +struct uwsgi_buffer *uwsgi_buffer_new(size_t); +int uwsgi_buffer_append(struct uwsgi_buffer *, char *, size_t); +int uwsgi_buffer_fix(struct uwsgi_buffer *, size_t); +int uwsgi_buffer_ensure(struct uwsgi_buffer *, size_t); +void uwsgi_buffer_destroy(struct uwsgi_buffer *); +int uwsgi_buffer_u8(struct uwsgi_buffer *, uint8_t); +int uwsgi_buffer_byte(struct uwsgi_buffer *, char); +int uwsgi_buffer_u16le(struct uwsgi_buffer *, uint16_t); +int uwsgi_buffer_u16be(struct uwsgi_buffer *, uint16_t); +int uwsgi_buffer_u32be(struct uwsgi_buffer *, uint32_t); +int uwsgi_buffer_u32le(struct uwsgi_buffer *, uint32_t); +int uwsgi_buffer_u24be(struct uwsgi_buffer *, uint32_t); +int uwsgi_buffer_u64be(struct uwsgi_buffer *, uint64_t); +int uwsgi_buffer_num64(struct uwsgi_buffer *, int64_t); +int uwsgi_buffer_append_keyval(struct uwsgi_buffer *, char *, uint16_t, char *, uint16_t); +int uwsgi_buffer_append_keyval32(struct uwsgi_buffer *, char *, uint32_t, char *, uint32_t); +int uwsgi_buffer_append_keynum(struct uwsgi_buffer *, char *, uint16_t, int64_t); +int uwsgi_buffer_append_valnum(struct uwsgi_buffer *, int64_t); +int uwsgi_buffer_append_ipv4(struct uwsgi_buffer *, void *); +int uwsgi_buffer_append_keyipv4(struct uwsgi_buffer *, char *, uint16_t, void *); +int uwsgi_buffer_decapitate(struct uwsgi_buffer *, size_t); +int uwsgi_buffer_append_base64(struct uwsgi_buffer *, char *, size_t); +int uwsgi_buffer_insert(struct uwsgi_buffer *, size_t, char *, size_t); +int uwsgi_buffer_insert_chunked(struct uwsgi_buffer *, size_t, size_t); +int uwsgi_buffer_append_chunked(struct uwsgi_buffer *, size_t); - ssize_t uwsgi_buffer_write_simple(struct wsgi_request *, struct uwsgi_buffer *); +ssize_t uwsgi_buffer_write_simple(struct wsgi_request *, struct uwsgi_buffer *); struct uwsgi_buffer *uwsgi_to_http(struct wsgi_request *, char *, uint16_t, char *, uint16_t); @@ -3802,6 +3801,10 @@ void uwsgi_unblock_signal(int); int uwsgi_worker_is_busy(int); +void uwsgi_manage_exception(struct wsgi_request *, int); +int uwsgi_exceptions_catch(struct wsgi_request *); +uint64_t uwsgi_worker_exceptions(int); + #define uwsgi_response_add_connection_close(x) uwsgi_response_add_header(x, "Connection", 10, "close", 5) #define uwsgi_response_add_content_type(x, y, z) uwsgi_response_add_header(x, "Content-Type", 12, y, z)