|
32 | 32 | #include "zend_exceptions.h" |
33 | 33 | #include "zend_generators.h" |
34 | 34 | #include "zend_ini.h" |
| 35 | +#include "zend_builtin_functions.h" |
35 | 36 |
|
36 | 37 | #define METHOD(name) PHP_METHOD(Async_Coroutine, name) |
37 | 38 | #define THIS_COROUTINE ((async_coroutine_t *) ZEND_ASYNC_OBJECT_TO_EVENT(Z_OBJ_P(ZEND_THIS))) |
@@ -1333,9 +1334,40 @@ METHOD(getException) |
1333 | 1334 |
|
1334 | 1335 | METHOD(getTrace) |
1335 | 1336 | { |
1336 | | - // TODO: Implement debug trace collection |
1337 | | - // This would require fiber stack trace functionality |
1338 | | - array_init(return_value); |
| 1337 | + zend_long options = DEBUG_BACKTRACE_PROVIDE_OBJECT; |
| 1338 | + zend_long limit = 0; |
| 1339 | + |
| 1340 | + ZEND_PARSE_PARAMETERS_START(0, 2) |
| 1341 | + Z_PARAM_OPTIONAL |
| 1342 | + Z_PARAM_LONG(options) |
| 1343 | + Z_PARAM_LONG(limit) |
| 1344 | + ZEND_PARSE_PARAMETERS_END(); |
| 1345 | + |
| 1346 | + async_coroutine_t *coroutine = THIS_COROUTINE; |
| 1347 | + async_fiber_context_t *fiber_context = coroutine->fiber_context; |
| 1348 | + |
| 1349 | + // Return empty array if coroutine is not suspended or has no fiber context |
| 1350 | + if (fiber_context == NULL || |
| 1351 | + fiber_context->context.status != ZEND_FIBER_STATUS_SUSPENDED || |
| 1352 | + !fiber_context->execute_data) { |
| 1353 | + array_init(return_value); |
| 1354 | + return; |
| 1355 | + } |
| 1356 | + |
| 1357 | + // Switch to the coroutine's VM stack to generate the backtrace |
| 1358 | + zend_vm_stack orig_vm_stack = EG(vm_stack); |
| 1359 | + zend_execute_data *orig_execute_data = EG(current_execute_data); |
| 1360 | + |
| 1361 | + EG(vm_stack) = fiber_context->vm_stack; |
| 1362 | + EG(current_execute_data) = fiber_context->execute_data; |
| 1363 | + |
| 1364 | + // Generate the backtrace using Zend's built-in function |
| 1365 | + // skip_last = 0 (don't skip any frames) |
| 1366 | + zend_fetch_debug_backtrace(return_value, 0, (int)options, (int)limit); |
| 1367 | + |
| 1368 | + // Restore original VM stack and execute data |
| 1369 | + EG(vm_stack) = orig_vm_stack; |
| 1370 | + EG(current_execute_data) = orig_execute_data; |
1339 | 1371 | } |
1340 | 1372 |
|
1341 | 1373 | // Location Methods |
|
0 commit comments