| Index: src/inspector/v8-stack-trace-impl.cc | 
| diff --git a/src/inspector/v8-stack-trace-impl.cc b/src/inspector/v8-stack-trace-impl.cc | 
| index 962a00a773ded450312a8c5005601178c0773f76..07172a4619b58107b9bcc219945ba82a8f7f4a1e 100644 | 
| --- a/src/inspector/v8-stack-trace-impl.cc | 
| +++ b/src/inspector/v8-stack-trace-impl.cc | 
| @@ -141,10 +141,13 @@ std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::create( | 
| maxAsyncCallChainDepth = 1; | 
| } | 
|  | 
| -  // Only the top stack in the chain may be empty, so ensure that second stack | 
| -  // is non-empty (it's the top of appended chain). | 
| -  if (asyncCallChain && asyncCallChain->isEmpty()) | 
| +  // Only the top stack in the chain may be empty and doesn't contain creation | 
| +  // stack , so ensure that second stack is non-empty (it's the top of appended | 
| +  // chain). | 
| +  if (asyncCallChain && asyncCallChain->isEmpty() && | 
| +      !asyncCallChain->m_creation) { | 
| asyncCallChain = asyncCallChain->m_parent.get(); | 
| +  } | 
|  | 
| if (stackTrace.IsEmpty() && !asyncCallChain) return nullptr; | 
|  | 
| @@ -180,9 +183,11 @@ std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::capture( | 
|  | 
| std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::cloneImpl() { | 
| std::vector<Frame> framesCopy(m_frames); | 
| -  return std::unique_ptr<V8StackTraceImpl>( | 
| +  std::unique_ptr<V8StackTraceImpl> copy( | 
| new V8StackTraceImpl(m_contextGroupId, m_description, framesCopy, | 
| m_parent ? m_parent->cloneImpl() : nullptr)); | 
| +  if (m_creation) copy->setCreation(m_creation->cloneImpl()); | 
| +  return copy; | 
| } | 
|  | 
| std::unique_ptr<V8StackTrace> V8StackTraceImpl::clone() { | 
| @@ -205,6 +210,19 @@ V8StackTraceImpl::V8StackTraceImpl(int contextGroupId, | 
|  | 
| V8StackTraceImpl::~V8StackTraceImpl() {} | 
|  | 
| +void V8StackTraceImpl::setCreation(std::unique_ptr<V8StackTraceImpl> creation) { | 
| +  m_creation = std::move(creation); | 
| +  // When async call chain is empty but doesn't contain useful schedule stack | 
| +  // and parent async call chain contains creationg stack but doesn't | 
| +  // synchronous we can merge them together. | 
| +  // e.g. Promise ThenableJob. | 
| +  if (m_parent && isEmpty() && m_description == m_parent->m_description && | 
| +      !m_parent->m_creation) { | 
| +    m_frames.swap(m_parent->m_frames); | 
| +    m_parent = std::move(m_parent->m_parent); | 
| +  } | 
| +} | 
| + | 
| StringView V8StackTraceImpl::topSourceURL() const { | 
| DCHECK(m_frames.size()); | 
| return toStringView(m_frames[0].m_scriptName); | 
| @@ -243,6 +261,10 @@ V8StackTraceImpl::buildInspectorObjectImpl() const { | 
| .build(); | 
| if (!m_description.isEmpty()) stackTrace->setDescription(m_description); | 
| if (m_parent) stackTrace->setParent(m_parent->buildInspectorObjectImpl()); | 
| +  if (m_creation && m_creation->m_frames.size()) { | 
| +    stackTrace->setPromiseCreationFrame( | 
| +        m_creation->m_frames[0].buildInspectorObject()); | 
| +  } | 
| return stackTrace; | 
| } | 
|  | 
|  |