diff --git a/hphp/runtime/vm/bytecode.cpp b/hphp/runtime/vm/bytecode.cpp index c6c45d063..7c85672cf 100644 --- a/hphp/runtime/vm/bytecode.cpp +++ b/hphp/runtime/vm/bytecode.cpp @@ -2390,7 +2390,14 @@ Array VMExecutionContext::debugBacktrace(bool skip /* = false */, prevFp->m_func->unit()->getLineNumber(pc), true); } // check for include - StringData *funcname = const_cast(fp->m_func->name()); + String funcname = const_cast(fp->m_func->name()); + if (fp->m_func->isGenerator()) { + // retrieve the original function name from the inner continuation + TypedValue* tv = frame_local(fp, 0); + assert(tv->m_type == HPHP::KindOfObject); + funcname = static_cast( + tv->m_data.pobj)->t_getorigfuncname(); + } if (fp->m_func->isClosureBody()) { static StringData* s_closure_label = StringData::GetStaticString("{closure}"); @@ -2401,8 +2408,8 @@ Array VMExecutionContext::debugBacktrace(bool skip /* = false */, if (!prevFp) continue; funcname = s_include; } - frame.set(String(s_function), String(funcname), true); - if (funcname != s_include) { + frame.set(String(s_function), funcname, true); + if (!funcname.same(s_include)) { // Closures have an m_this but they aren't in object context Class* ctx = arGetContextClass(fp); if (ctx != nullptr && !fp->m_func->isClosureBody()) { @@ -2418,7 +2425,7 @@ Array VMExecutionContext::debugBacktrace(bool skip /* = false */, } } Array args = Array::Create(); - if (funcname == s_include) { + if (funcname.same(s_include)) { if (depth) { args.append(String(const_cast( fp->m_func->unit()->filepath()))); diff --git a/hphp/test/vm/debug_backtrace_continuation.php b/hphp/test/vm/debug_backtrace_continuation.php new file mode 100644 index 000000000..051152299 --- /dev/null +++ b/hphp/test/vm/debug_backtrace_continuation.php @@ -0,0 +1,13 @@ +next(); + $gen->send(null); +} + +my_wrapper(); diff --git a/hphp/test/vm/debug_backtrace_continuation.php.exp b/hphp/test/vm/debug_backtrace_continuation.php.exp new file mode 100644 index 000000000..b32a4b20a --- /dev/null +++ b/hphp/test/vm/debug_backtrace_continuation.php.exp @@ -0,0 +1,50 @@ +array(3) { + [0]=> + array(4) { + ["file"]=> + string(0) "" + ["line"]=> + int(-1) + ["function"]=> + string(12) "my_generator" + ["args"]=> + array(1) { + [0]=> + object(Continuation)#1 (0) { + } + } + } + [1]=> + array(7) { + ["file"]=> + string() "hphp/test/vm/debug_backtrace_continuation.php" + ["line"]=> + int(10) + ["function"]=> + string(4) "send" + ["class"]=> + string(12) "Continuation" + ["object"]=> + object(Continuation)#1 (0) { + } + ["type"]=> + string(2) "->" + ["args"]=> + array(1) { + [0]=> + NULL + } + } + [2]=> + array(4) { + ["file"]=> + string() "hphp/test/vm/debug_backtrace_continuation.php" + ["line"]=> + int(13) + ["function"]=> + string(10) "my_wrapper" + ["args"]=> + array(0) { + } + } +} diff --git a/hphp/test/vm/debug_backtrace_continuation.php.filter b/hphp/test/vm/debug_backtrace_continuation.php.filter new file mode 100755 index 000000000..57501ae16 --- /dev/null +++ b/hphp/test/vm/debug_backtrace_continuation.php.filter @@ -0,0 +1,2 @@ +#!/bin/bash +sed -e 's/string(.*) ".*\/hphp/string() "hphp/g'