1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_INSPECTOR_V8_STACK_TRACE_IMPL_H_
6 #define V8_INSPECTOR_V8_STACK_TRACE_IMPL_H_
7 
8 #include <memory>
9 #include <vector>
10 
11 #include "include/v8-inspector.h"
12 #include "include/v8.h"
13 #include "src/base/macros.h"
14 #include "src/inspector/protocol/Runtime.h"
15 #include "src/inspector/string-16.h"
16 
17 namespace v8_inspector {
18 
19 class AsyncStackTrace;
20 class V8Debugger;
21 class WasmTranslation;
22 struct V8StackTraceId;
23 
24 class StackFrame {
25  public:
26   explicit StackFrame(v8::Local<v8::StackFrame> frame);
27   ~StackFrame() = default;
28 
29   void translate(WasmTranslation* wasmTranslation);
30 
31   const String16& functionName() const;
32   const String16& scriptId() const;
33   const String16& sourceURL() const;
34   int lineNumber() const;    // 0-based.
35   int columnNumber() const;  // 0-based.
36   std::unique_ptr<protocol::Runtime::CallFrame> buildInspectorObject(
37       V8InspectorClient* client) const;
38   bool isEqual(StackFrame* frame) const;
39 
40  private:
41   String16 m_functionName;
42   String16 m_scriptId;
43   String16 m_sourceURL;
44   int m_lineNumber;    // 0-based.
45   int m_columnNumber;  // 0-based.
46   bool m_hasSourceURLComment;
47 };
48 
49 class V8StackTraceImpl : public V8StackTrace {
50  public:
51   static void setCaptureStackTraceForUncaughtExceptions(v8::Isolate*,
52                                                         bool capture);
53   static const int maxCallStackSizeToCapture = 200;
54   static std::unique_ptr<V8StackTraceImpl> create(V8Debugger*,
55                                                   int contextGroupId,
56                                                   v8::Local<v8::StackTrace>,
57                                                   int maxStackSize);
58   static std::unique_ptr<V8StackTraceImpl> capture(V8Debugger*,
59                                                    int contextGroupId,
60                                                    int maxStackSize);
61 
62   ~V8StackTraceImpl() override;
63   std::unique_ptr<protocol::Runtime::StackTrace> buildInspectorObjectImpl(
64       V8Debugger* debugger) const;
65 
66   // V8StackTrace implementation.
67   // This method drops the async stack trace.
68   std::unique_ptr<V8StackTrace> clone() override;
69   bool isEmpty() const override;
70   StringView topSourceURL() const override;
71   int topLineNumber() const override;    // 1-based.
72   int topColumnNumber() const override;  // 1-based.
73   StringView topScriptId() const override;
74   StringView topFunctionName() const override;
75   std::unique_ptr<protocol::Runtime::API::StackTrace> buildInspectorObject()
76       const override;
77   std::unique_ptr<StringBuffer> toString() const override;
78 
79   bool isEqualIgnoringTopFrame(V8StackTraceImpl* stackTrace) const;
80 
81  private:
82   V8StackTraceImpl(std::vector<std::shared_ptr<StackFrame>> frames,
83                    int maxAsyncDepth,
84                    std::shared_ptr<AsyncStackTrace> asyncParent,
85                    const V8StackTraceId& externalParent);
86 
87   class StackFrameIterator {
88    public:
89     explicit StackFrameIterator(const V8StackTraceImpl* stackTrace);
90 
91     void next();
92     StackFrame* frame();
93     bool done();
94 
95    private:
96     std::vector<std::shared_ptr<StackFrame>>::const_iterator m_currentIt;
97     std::vector<std::shared_ptr<StackFrame>>::const_iterator m_currentEnd;
98     AsyncStackTrace* m_parent;
99   };
100 
101   std::vector<std::shared_ptr<StackFrame>> m_frames;
102   int m_maxAsyncDepth;
103   std::weak_ptr<AsyncStackTrace> m_asyncParent;
104   V8StackTraceId m_externalParent;
105 
106   DISALLOW_COPY_AND_ASSIGN(V8StackTraceImpl);
107 };
108 
109 class AsyncStackTrace {
110  public:
111   static std::shared_ptr<AsyncStackTrace> capture(V8Debugger*,
112                                                   int contextGroupId,
113                                                   const String16& description,
114                                                   int maxStackSize);
115   static uintptr_t store(V8Debugger* debugger,
116                          std::shared_ptr<AsyncStackTrace> stack);
117 
118   std::unique_ptr<protocol::Runtime::StackTrace> buildInspectorObject(
119       V8Debugger* debugger, int maxAsyncDepth) const;
120 
121   int contextGroupId() const;
122   const String16& description() const;
123   std::weak_ptr<AsyncStackTrace> parent() const;
124   bool isEmpty() const;
externalParent()125   const V8StackTraceId& externalParent() const { return m_externalParent; }
126 
frames()127   const std::vector<std::shared_ptr<StackFrame>>& frames() const {
128     return m_frames;
129   }
130 
131  private:
132   AsyncStackTrace(int contextGroupId, const String16& description,
133                   std::vector<std::shared_ptr<StackFrame>> frames,
134                   std::shared_ptr<AsyncStackTrace> asyncParent,
135                   const V8StackTraceId& externalParent);
136 
137   int m_contextGroupId;
138   uintptr_t m_id;
139   String16 m_description;
140 
141   std::vector<std::shared_ptr<StackFrame>> m_frames;
142   std::weak_ptr<AsyncStackTrace> m_asyncParent;
143   V8StackTraceId m_externalParent;
144 
145   DISALLOW_COPY_AND_ASSIGN(AsyncStackTrace);
146 };
147 
148 }  // namespace v8_inspector
149 
150 #endif  // V8_INSPECTOR_V8_STACK_TRACE_IMPL_H_
151