Skip to content

Commit af37377

Browse files
CopilotEdmondDantes
andcommitted
Implement Coroutine::getTrace() method with parameters
Co-authored-by: EdmondDantes <1571649+EdmondDantes@users.noreply.github.com>
1 parent 8f6b91a commit af37377

File tree

3 files changed

+44
-5
lines changed

3 files changed

+44
-5
lines changed

coroutine.c

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "zend_exceptions.h"
3333
#include "zend_generators.h"
3434
#include "zend_ini.h"
35+
#include "zend_builtin_functions.h"
3536

3637
#define METHOD(name) PHP_METHOD(Async_Coroutine, name)
3738
#define THIS_COROUTINE ((async_coroutine_t *) ZEND_ASYNC_OBJECT_TO_EVENT(Z_OBJ_P(ZEND_THIS)))
@@ -1333,9 +1334,40 @@ METHOD(getException)
13331334

13341335
METHOD(getTrace)
13351336
{
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;
13391371
}
13401372

13411373
// Location Methods

coroutine.stub.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,13 @@ public function getException(): mixed {}
4242

4343
/**
4444
* Returns the Coroutine debug trace.
45+
* If the coroutine is in the suspended state, returns a backtrace array.
46+
* Otherwise, returns an empty array.
47+
*
48+
* @param int $options Options for the backtrace (DEBUG_BACKTRACE_PROVIDE_OBJECT, DEBUG_BACKTRACE_IGNORE_ARGS)
49+
* @param int $limit Maximum number of stack frames to return (0 for no limit)
4550
*/
46-
public function getTrace(): array {}
51+
public function getTrace(int $options = DEBUG_BACKTRACE_PROVIDE_OBJECT, int $limit = 0): array {}
4752

4853
/**
4954
* Return spawn file and line.

coroutine_arginfo.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 866a851c4d87feafd6585532d622426dc453710f */
2+
* Stub hash: 35d332163bf92ed3cad35c83017aaa67d650aa9d */
33

44
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Async_Coroutine_getId, 0, 0, IS_LONG, 0)
55
ZEND_END_ARG_INFO()
@@ -16,6 +16,8 @@ ZEND_END_ARG_INFO()
1616
#define arginfo_class_Async_Coroutine_getException arginfo_class_Async_Coroutine_getResult
1717

1818
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Async_Coroutine_getTrace, 0, 0, IS_ARRAY, 0)
19+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "DEBUG_BACKTRACE_PROVIDE_OBJECT")
20+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, limit, IS_LONG, 0, "0")
1921
ZEND_END_ARG_INFO()
2022

2123
#define arginfo_class_Async_Coroutine_getSpawnFileAndLine arginfo_class_Async_Coroutine_getTrace

0 commit comments

Comments
 (0)