Obtain the backtrace for the exception as a string (instead of an array) */
ZEND_METHOD(exception, getTraceAsString)
{
- zval *trace;
- char *res, **str, *s_tmp;
- int res_len = 0, *len = &res_len, num = 0;
+ zval *trace, *frame, rv;
+ zend_ulong index;
+ smart_str str = {0};
+ uint32_t num = 0;
DEFAULT_0_PARAMS;
-
- res = estrdup("");
- str = &res;
- trace = zend_read_property(default_exception_ce, getThis(), "trace", sizeof("trace")-1, 1 TSRMLS_CC);
+ trace = zend_read_property(base_exception_ce, getThis(), "trace", sizeof("trace")-1, 1, &rv);
- if(Z_TYPE_P(trace) != IS_ARRAY) {
+ if (Z_TYPE_P(trace) != IS_ARRAY) {
RETURN_FALSE;
}
- zend_hash_apply_with_arguments(Z_ARRVAL_P(trace) TSRMLS_CC, (apply_func_args_t)_build_trace_string, 3, str, len, &num);
+ ZEND_HASH_FOREACH_NUM_KEY_VAL(Z_ARRVAL_P(trace), index, frame) {
+ if (Z_TYPE_P(frame) != IS_ARRAY) {
+ zend_error(E_WARNING, "Expected array for frame %pu", index);
+ continue;
+ }
+
+ _build_trace_string(&str, Z_ARRVAL_P(frame), num++);
+ } ZEND_HASH_FOREACH_END();
- s_tmp = emalloc(1 + MAX_LENGTH_OF_LONG + 7 + 1);
- sprintf(s_tmp, "#%d {main}", num);
- TRACE_APPEND_STRL(s_tmp, strlen(s_tmp));
- efree(s_tmp);
+ smart_str_appendc(&str, '#');
+ smart_str_append_long(&str, num);
+ smart_str_appends(&str, " {main}");
+ smart_str_0(&str);
- res[res_len] = '\0';
- RETURN_STRINGL(res, res_len, 0);
+ RETURN_NEW_STR(str.s);
}
/* }}} */