/** * Adds a variable to the debug output * * @param mixed $var * @param string $key * @return Phalcon\Debug */ PHP_METHOD(Phalcon_Debug, debugVar){ zval *var, *key = NULL, *ztime, *backtrace, *data; PHALCON_MM_GROW(); phalcon_fetch_params(1, 1, 1, &var, &key); if (!key) { PHALCON_INIT_VAR(key); } PHALCON_INIT_VAR(ztime); ZVAL_LONG(ztime, (long) time(NULL)); PHALCON_INIT_VAR(backtrace); #if PHP_VERSION_ID < 50400 #ifdef DEBUG_BACKTRACE_PROVIDE_OBJECT zend_fetch_debug_backtrace(backtrace, 0, DEBUG_BACKTRACE_PROVIDE_OBJECT TSRMLS_CC); #else zend_fetch_debug_backtrace(backtrace, 0, 1 TSRMLS_CC); #endif #else zend_fetch_debug_backtrace(backtrace, 0, DEBUG_BACKTRACE_PROVIDE_OBJECT, 0 TSRMLS_CC); #endif PHALCON_INIT_VAR(data); array_init_size(data, 3); phalcon_array_append(&data, var, PH_SEPARATE); phalcon_array_append(&data, backtrace, PH_SEPARATE); phalcon_array_append(&data, ztime, PH_SEPARATE); phalcon_update_property_array_append(this_ptr, SL("_data"), data TSRMLS_CC); RETURN_THIS(); }
static PHP_METHOD(swoole_coroutine_util, getBackTrace) { zend_long cid; zend_long options = DEBUG_BACKTRACE_PROVIDE_OBJECT; zend_long limit = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|ll", &cid) == FAILURE) { return; } if (cid == sw_get_current_cid()) { zend_fetch_debug_backtrace(return_value, 0, options, limit); } else { coro_task *task = (coro_task *) coroutine_get_task_by_cid(cid); if (task == NULL) { RETURN_FALSE; } zend_execute_data *ex_backup = EG(current_execute_data); EG(current_execute_data) = task->yield_execute_data; zend_fetch_debug_backtrace(return_value, 0, options, limit); EG(current_execute_data) = ex_backup; } }
static zend_object *zend_default_exception_new_ex(zend_class_entry *class_type, int skip_top_traces) /* {{{ */ { zval obj; zend_object *object; zval trace; zend_class_entry *base_ce; zend_string *filename; Z_OBJ(obj) = object = zend_objects_new(class_type); Z_OBJ_HT(obj) = &default_exception_handlers; object_properties_init(object, class_type); if (EG(current_execute_data)) { zend_fetch_debug_backtrace(&trace, skip_top_traces, 0, 0); } else { array_init(&trace); } Z_SET_REFCOUNT(trace, 0); base_ce = i_get_exception_base(&obj); if (EXPECTED(class_type != zend_ce_parse_error || !(filename = zend_get_compiled_filename()))) { zend_update_property_string(base_ce, &obj, "file", sizeof("file")-1, zend_get_executed_filename()); zend_update_property_long(base_ce, &obj, "line", sizeof("line")-1, zend_get_executed_lineno()); } else { zend_update_property_str(base_ce, &obj, "file", sizeof("file")-1, filename); zend_update_property_long(base_ce, &obj, "line", sizeof("line")-1, zend_get_compiled_lineno()); } zend_update_property(base_ce, &obj, "trace", sizeof("trace")-1, &trace); return object; }
/** * Adds a variable to the debug output * * @param mixed $var * @param string $key * @return Phalcon\Debug */ PHP_METHOD(Phalcon_Debug, debugVar) { zval *var, *key = NULL, *ztime, *backtrace, *data; PHALCON_MM_GROW(); phalcon_fetch_params(0, 1, 1, &var, &key); if (!key) { key = &PHALCON_GLOBAL(z_null); } PHALCON_INIT_VAR(ztime); ZVAL_LONG(ztime, (long) time(NULL)); PHALCON_INIT_VAR(backtrace); zend_fetch_debug_backtrace(backtrace, 0, DEBUG_BACKTRACE_PROVIDE_OBJECT, 0); PHALCON_INIT_VAR(data); array_init_size(data, 3); phalcon_array_append(data, var, PH_COPY); phalcon_array_append(data, backtrace, PH_COPY); phalcon_array_append(data, ztime, PH_COPY); phalcon_update_property_array_append(getThis(), SL("_data"), data); RETURN_THIS(); }
void symfony_debug_error_cb(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) { TSRMLS_FETCH(); zval *retval; switch (type) { case E_ERROR: case E_PARSE: case E_CORE_ERROR: case E_CORE_WARNING: case E_COMPILE_ERROR: case E_COMPILE_WARNING: ALLOC_INIT_ZVAL(retval); #if IS_PHP_53 zend_fetch_debug_backtrace(retval, 1, 0 TSRMLS_CC); #else zend_fetch_debug_backtrace(retval, 1, 0, 0 TSRMLS_CC); #endif SYMFONY_DEBUG_G(debug_bt) = retval; } SYMFONY_DEBUG_G(old_error_cb)(type, error_filename, error_lineno, format, args); }
static zend_object *zend_default_exception_new_ex(zend_class_entry *class_type, int skip_top_traces) /* {{{ */ { zval obj, tmp; zend_object *object; zval trace; zend_class_entry *base_ce; zend_string *filename; Z_OBJ(obj) = object = zend_objects_new(class_type); Z_OBJ_HT(obj) = &default_exception_handlers; object_properties_init(object, class_type); if (EG(current_execute_data)) { zend_fetch_debug_backtrace(&trace, skip_top_traces, 0, 0); } else { array_init(&trace); } Z_SET_REFCOUNT(trace, 0); base_ce = i_get_exception_base(&obj); if (EXPECTED((class_type != zend_ce_parse_error && class_type != zend_ce_compile_error) || !(filename = zend_get_compiled_filename()))) { ZVAL_STRING(&tmp, zend_get_executed_filename()); zend_update_property_ex(base_ce, &obj, ZSTR_KNOWN(ZEND_STR_FILE), &tmp); zval_ptr_dtor(&tmp); ZVAL_LONG(&tmp, zend_get_executed_lineno()); zend_update_property_ex(base_ce, &obj, ZSTR_KNOWN(ZEND_STR_LINE), &tmp); } else { ZVAL_STR(&tmp, filename); zend_update_property_ex(base_ce, &obj, ZSTR_KNOWN(ZEND_STR_FILE), &tmp); ZVAL_LONG(&tmp, zend_get_compiled_lineno()); zend_update_property_ex(base_ce, &obj, ZSTR_KNOWN(ZEND_STR_LINE), &tmp); } zend_update_property_ex(base_ce, &obj, ZSTR_KNOWN(ZEND_STR_TRACE), &trace); return object; }
/** * Applies a format to a message before sending it to the log * * @param string $message * @param int $type * @param int $timestamp * @param array $context * @return string */ PHP_METHOD(Phalcon_Logger_Formatter_Firephp, format) { zval *message, *type, *type_str = NULL, *timestamp, *context, *interpolated = NULL; zval *payload, *body, *backtrace = NULL, *meta, *encoded; zval *show_backtrace, *enable_labels; int i_show_backtrace, i_enable_labels; smart_str result = { NULL, 0, 0 }; uint i; Bucket *p; phalcon_fetch_params(0, 4, 0, &message, &type, ×tamp, &context); /* * We intentionally do not use Phalcon's MM for better performance. * All variables allocated with ALLOC_INIT_ZVAL() will have * their reference count set to 1 and therefore they can be nicely * put into the result array; when that array will be destroyed, * all inserted variables will be automatically destroyed, too * and we will just save some time by not using Z_ADDREF_P and Z_DELREF_P */ if (Z_TYPE_P(context) == IS_ARRAY) { PHALCON_CALL_METHODW(&interpolated, this_ptr, "interpolate", message, context); } else { interpolated = message; Z_ADDREF_P(interpolated); } { zval *params[] = { type }; if (FAILURE == phalcon_call_method(&type_str, this_ptr, "gettypestring", 1, params TSRMLS_CC)) { zval_ptr_dtor(&interpolated); return; } } show_backtrace = phalcon_fetch_nproperty_this(getThis(), SL("_showBacktrace"), PH_NOISY TSRMLS_CC); enable_labels = phalcon_fetch_nproperty_this(getThis(), SL("_enableLabels"), PH_NOISY TSRMLS_CC); i_show_backtrace = zend_is_true(show_backtrace); i_enable_labels = zend_is_true(enable_labels); /* * Get the backtrace. This differs for different PHP versions. * 5.3.6+ allows us to skip the function arguments which will save some memory * For 5.4+ there is an extra argument. */ if (i_show_backtrace) { ALLOC_INIT_ZVAL(backtrace); #if PHP_VERSION_ID < 50306 zend_fetch_debug_backtrace(backtrace, 1, 0 TSRMLS_CC); #elif PHP_VERSION_ID < 50400 zend_fetch_debug_backtrace(backtrace, 1, DEBUG_BACKTRACE_IGNORE_ARGS TSRMLS_CC); #else zend_fetch_debug_backtrace(backtrace, 1, DEBUG_BACKTRACE_IGNORE_ARGS, 0 TSRMLS_CC); #endif if (Z_TYPE_P(backtrace) == IS_ARRAY) { HashPosition pos; HashTable *ht = Z_ARRVAL_P(backtrace); zval **ppzval; int found = 0; ulong idx; char *key; uint key_len; /* * At this point we know that the backtrace is the array. * Again, we intentionally do not use Phalcon's API because we know * that we are working with the array / hash table and thus we can * save some time by omitting Z_TYPE_P(x) == IS_ARRAY checks */ for ( zend_hash_internal_pointer_reset_ex(ht, &pos); zend_hash_has_more_elements_ex(ht, &pos) == SUCCESS; ) { zend_hash_get_current_data_ex(ht, (void**)&ppzval, &pos); zend_hash_get_current_key_ex(ht, &key, &key_len, &idx, 0, &pos); zend_hash_move_forward_ex(ht, &pos); if (Z_TYPE_PP(ppzval) == IS_ARRAY) { /* * Here we need to skip the latest calls into Phalcon's core. * Calls to Zend internal functions will have "file" index not set. * We remove these entries from the array. */ if (!found && !zend_hash_quick_exists(Z_ARRVAL_PP(ppzval), SS("file"), zend_inline_hash_func(SS("file")))) { zend_hash_index_del(ht, idx); } else { /* * Remove args and object indices. They usually give * too much information; this is not suitable to send * in the HTTP headers */ zend_hash_quick_del(Z_ARRVAL_PP(ppzval), "args", sizeof("args"), zend_inline_hash_func(SS("args"))); zend_hash_quick_del(Z_ARRVAL_PP(ppzval), "object", sizeof("object"), zend_inline_hash_func(SS("object"))); found = 1; } } } /* * Now we need to renumber the hash table because we removed several * heading elements. If we don't do this, json_encode() will convert * this array to a JavaScript object which is an unwanted side effect */ p = ht->pListHead; i = 0; while (p != NULL) { p->nKeyLength = 0; p->h = i++; p = p->pListNext; } ht->nNextFreeElement = i; zend_hash_rehash(ht); } } /* * The result will looks like this: * * array( * array('Type' => 'message type', 'Label' => 'message'), * array('backtrace' => array(backtrace goes here) * ) */ MAKE_STD_ZVAL(payload); array_init_size(payload, 2); MAKE_STD_ZVAL(meta); array_init_size(meta, 4); add_assoc_zval_ex(meta, SS("Type"), type_str); if (i_show_backtrace && Z_TYPE_P(backtrace) == IS_ARRAY) { zval **ppzval; if (likely(SUCCESS == zend_hash_index_find(Z_ARRVAL_P(backtrace), 0, (void**)&ppzval)) && likely(Z_TYPE_PP(ppzval) == IS_ARRAY)) { zval **file = NULL, **line = NULL; zend_hash_quick_find(Z_ARRVAL_PP(ppzval), SS("file"), zend_inline_hash_func(SS("file")), (void**)&file); zend_hash_quick_find(Z_ARRVAL_PP(ppzval), SS("line"), zend_inline_hash_func(SS("line")), (void**)&line); if (likely(file != NULL)) { Z_ADDREF_PP(file); add_assoc_zval_ex(meta, SS("File"), *file); } if (likely(line != NULL)) { Z_ADDREF_PP(line); add_assoc_zval_ex(meta, SS("Line"), *line); } } } if (i_enable_labels) { add_assoc_zval_ex(meta, SS("Label"), interpolated); } if (!i_enable_labels && !i_show_backtrace) { body = interpolated; } else if (i_enable_labels && !i_show_backtrace) { MAKE_STD_ZVAL(body); ZVAL_EMPTY_STRING(body); } else { MAKE_STD_ZVAL(body); array_init_size(body, 2); if (i_show_backtrace) { add_assoc_zval_ex(body, SS("backtrace"), backtrace); } if (!i_enable_labels) { add_assoc_zval_ex(body, SS("message"), interpolated); } } add_next_index_zval(payload, meta); add_next_index_zval(payload, body); /* Convert everything to JSON */ ALLOC_INIT_ZVAL(encoded); if (FAILURE == phalcon_json_encode(encoded, payload, 0 TSRMLS_CC)) { zval_ptr_dtor(&payload); zval_ptr_dtor(&encoded); return; } /* As promised, kill the payload and all associated elements */ zval_ptr_dtor(&payload); /* * We don't want to use Phalcon's concatenation API because it * requires the memory manager. Therefore we fall back to using smart strings. * smart_str_alloc4() will allocate all required memory amount (plus some more) * in one go and this allows us to avoid performance penalties due to * memory reallocations. */ if (Z_TYPE_P(encoded) == IS_STRING && Z_STRVAL_P(encoded) != NULL) { smart_str_alloc4(&result, (uint)(Z_STRLEN_P(encoded) + 2 + 5), 0, i); /* * The format is: * * <size>|[meta,body]| * * Meta and body are contained in encoded inside the array, as required * by the protocol specification * @see http://www.firephp.org/Wiki/Reference/Protocol */ smart_str_append_long(&result, Z_STRLEN_P(encoded)); smart_str_appendc(&result, '|'); smart_str_appendl(&result, Z_STRVAL_P(encoded), Z_STRLEN_P(encoded)); smart_str_appendc(&result, '|'); smart_str_0(&result); } /* We don't need the JSON message anymore */ zval_ptr_dtor(&encoded); /* Do not free the smart string because we steal its data for zval */ RETURN_STRINGL(result.c, result.len, 0); }
/* event must be initialized with MAKE_STD_ZVAL or similar and array_init before sending here */ void php_jam_capture_error_ex(zval *event, int type, const char *error_filename, const uint error_lineno, zend_bool free_event, const char *format, va_list args TSRMLS_DC) { zval **ppzval; va_list args_cp; int len; char *buffer; char uuid_str[PHP_JAM_UUID_LEN + 1]; TSRMLS_FETCH(); /* Generate unique identifier */ if (!php_jam_generate_uuid(uuid_str)) { php_jam_original_error_cb(E_WARNING TSRMLS_CC, "Failed to generate uuid"); return; } /* Capture superglobals */ if (JAM_G(log_get)) { _add_assoc_zval_helper(event, "_GET", sizeof("_GET") TSRMLS_CC); } if (JAM_G(log_post)) { _add_assoc_zval_helper(event, "_POST", sizeof("_POST") TSRMLS_CC); } if (JAM_G(log_cookie)) { _add_assoc_zval_helper(event, "_COOKIE", sizeof("_COOKIE") TSRMLS_CC); } if (JAM_G(log_session)) { _add_assoc_zval_helper(event, "_SESSION", sizeof("_SESSION") TSRMLS_CC); } if (JAM_G(log_server)) { _add_assoc_zval_helper(event, "_SERVER", sizeof("_SERVER") TSRMLS_CC); } if (JAM_G(log_env)) { _add_assoc_zval_helper(event, "_ENV", sizeof("_ENV") TSRMLS_CC); } if (JAM_G(log_files)) { _add_assoc_zval_helper(event, "_FILES", sizeof("_FILES") TSRMLS_CC); } /* Capture backtrace */ if (JAM_G(log_backtrace)) { zval *btrace; ALLOC_INIT_ZVAL(btrace); #if PHP_API_VERSION <= PHP_5_3_X_API_NO zend_fetch_debug_backtrace(btrace, 0, 0 TSRMLS_CC); #else // TODO: introduce a directive for the amount of stack frames returned instead of hard coded 1000? zend_fetch_debug_backtrace(btrace, 0, 0 TSRMLS_CC,1000); #endif add_assoc_zval(event, "backtrace", btrace); } va_copy(args_cp, args); len = vspprintf(&buffer, PG(log_errors_max_len), format, args_cp); va_end(args_cp); add_assoc_string(event, "error_message", buffer, 0); add_assoc_string(event, "filename", (char *)error_filename, 1); add_assoc_long(event, "line_number", error_lineno); add_assoc_long(event, "error_type", type); /* Set the last logged uuid into _SERVER */ add_assoc_string(event, "jam_event_uuid", uuid_str, 1); add_assoc_long(event, "jam_event_time", time(NULL)); /* Set the last logged uuid into _SERVER */ if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &ppzval) == SUCCESS) { add_assoc_string(*ppzval, "jam_last_uuid", uuid_str, 1); } /* Send to backend */ php_jam_storage_store_all(uuid_str, event, type, error_filename, error_lineno TSRMLS_CC); if (free_event) { zval_dtor(event); FREE_ZVAL(event); } }