• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "gtest/gtest.h"
2 #include "node.h"
3 #include "node_internals.h"
4 #include "node_test_fixture.h"
5 #include "req_wrap-inl.h"
6 #include "tracing/agent.h"
7 #include "v8.h"
8 #include "v8abbr.h"
9 
10 extern "C" {
11 extern uintptr_t
12     nodedbg_offset_HandleWrap__handle_wrap_queue___ListNode_HandleWrap;
13 extern uintptr_t
14     nodedbg_offset_Environment__handle_wrap_queue___Environment_HandleWrapQueue;
15 extern int debug_symbols_generated;
16 extern int nodedbg_const_ContextEmbedderIndex__kEnvironment__int;
17 extern uintptr_t
18     nodedbg_offset_Environment_HandleWrapQueue__head___ListNode_HandleWrap;
19 extern uintptr_t
20     nodedbg_offset_Environment__req_wrap_queue___Environment_ReqWrapQueue;
21 extern uintptr_t nodedbg_offset_ExternalString__data__uintptr_t;
22 extern uintptr_t nodedbg_offset_ListNode_ReqWrap__prev___uintptr_t;
23 extern uintptr_t nodedbg_offset_ListNode_ReqWrap__next___uintptr_t;
24 extern uintptr_t nodedbg_offset_ReqWrap__req_wrap_queue___ListNode_ReqWrapQueue;
25 extern uintptr_t nodedbg_offset_ListNode_HandleWrap__prev___uintptr_t;
26 extern uintptr_t nodedbg_offset_ListNode_HandleWrap__next___uintptr_t;
27 extern uintptr_t
28     nodedbg_offset_Environment_ReqWrapQueue__head___ListNode_ReqWrapQueue;
29 extern uintptr_t
30     nodedbg_offset_BaseObject__persistent_handle___v8_Persistent_v8_Object;
31 }
32 
33 
34 class DebugSymbolsTest : public EnvironmentTestFixture {};
35 
36 
37 class TestHandleWrap : public node::HandleWrap {
38  public:
39   SET_NO_MEMORY_INFO()
SET_MEMORY_INFO_NAME(TestHandleWrap)40   SET_MEMORY_INFO_NAME(TestHandleWrap)
41   SET_SELF_SIZE(TestHandleWrap)
42 
43   TestHandleWrap(node::Environment* env,
44                  v8::Local<v8::Object> object,
45                  uv_tcp_t* handle)
46       : node::HandleWrap(env,
47                          object,
48                          reinterpret_cast<uv_handle_t*>(handle),
49                          node::AsyncWrap::PROVIDER_TCPWRAP) {}
50 };
51 
52 
53 class TestReqWrap : public node::ReqWrap<uv_req_t> {
54  public:
55   SET_NO_MEMORY_INFO()
SET_MEMORY_INFO_NAME(TestReqWrap)56   SET_MEMORY_INFO_NAME(TestReqWrap)
57   SET_SELF_SIZE(TestReqWrap)
58 
59   TestReqWrap(node::Environment* env, v8::Local<v8::Object> object)
60       : node::ReqWrap<uv_req_t>(env,
61                                 object,
62                                 node::AsyncWrap::PROVIDER_FSREQCALLBACK) {}
63 };
64 
TEST_F(DebugSymbolsTest,ContextEmbedderEnvironmentIndex)65 TEST_F(DebugSymbolsTest, ContextEmbedderEnvironmentIndex) {
66   int kEnvironmentIndex = node::ContextEmbedderIndex::kEnvironment;
67   EXPECT_EQ(nodedbg_const_ContextEmbedderIndex__kEnvironment__int,
68             kEnvironmentIndex);
69 }
70 
TEST_F(DebugSymbolsTest,ExternalStringDataOffset)71 TEST_F(DebugSymbolsTest, ExternalStringDataOffset) {
72   EXPECT_EQ(nodedbg_offset_ExternalString__data__uintptr_t,
73             NODE_OFF_EXTSTR_DATA);
74 }
75 
76 class DummyBaseObject : public node::BaseObject {
77  public:
DummyBaseObject(node::Environment * env,v8::Local<v8::Object> obj)78   DummyBaseObject(node::Environment* env, v8::Local<v8::Object> obj) :
79     BaseObject(env, obj) {}
80 
81   SET_NO_MEMORY_INFO()
82   SET_MEMORY_INFO_NAME(DummyBaseObject)
83   SET_SELF_SIZE(DummyBaseObject)
84 };
85 
TEST_F(DebugSymbolsTest,BaseObjectPersistentHandle)86 TEST_F(DebugSymbolsTest, BaseObjectPersistentHandle) {
87   const v8::HandleScope handle_scope(isolate_);
88   const Argv argv;
89   Env env{handle_scope, argv};
90 
91   v8::Local<v8::ObjectTemplate> obj_templ = v8::ObjectTemplate::New(isolate_);
92   obj_templ->SetInternalFieldCount(1);
93 
94   v8::Local<v8::Object> object =
95       obj_templ->NewInstance(env.context()).ToLocalChecked();
96   node::BaseObjectPtr<DummyBaseObject> obj =
97       node::MakeDetachedBaseObject<DummyBaseObject>(*env, object);
98 
99   auto expected = reinterpret_cast<uintptr_t>(&obj->persistent());
100   auto calculated = reinterpret_cast<uintptr_t>(obj.get()) +
101       nodedbg_offset_BaseObject__persistent_handle___v8_Persistent_v8_Object;
102   EXPECT_EQ(expected, calculated);
103 }
104 
105 
TEST_F(DebugSymbolsTest,EnvironmentHandleWrapQueue)106 TEST_F(DebugSymbolsTest, EnvironmentHandleWrapQueue) {
107   const v8::HandleScope handle_scope(isolate_);
108   const Argv argv;
109   Env env{handle_scope, argv};
110 
111   auto expected = reinterpret_cast<uintptr_t>((*env)->handle_wrap_queue());
112   auto calculated = reinterpret_cast<uintptr_t>(*env) +
113       nodedbg_offset_Environment__handle_wrap_queue___Environment_HandleWrapQueue;  // NOLINT(whitespace/line_length)
114   EXPECT_EQ(expected, calculated);
115 }
116 
TEST_F(DebugSymbolsTest,EnvironmentReqWrapQueue)117 TEST_F(DebugSymbolsTest, EnvironmentReqWrapQueue) {
118   const v8::HandleScope handle_scope(isolate_);
119   const Argv argv;
120   Env env{handle_scope, argv};
121 
122   auto expected = reinterpret_cast<uintptr_t>((*env)->req_wrap_queue());
123   auto calculated = reinterpret_cast<uintptr_t>(*env) +
124       nodedbg_offset_Environment__req_wrap_queue___Environment_ReqWrapQueue;
125   EXPECT_EQ(expected, calculated);
126 }
127 
TEST_F(DebugSymbolsTest,HandleWrapList)128 TEST_F(DebugSymbolsTest, HandleWrapList) {
129   const v8::HandleScope handle_scope(isolate_);
130   const Argv argv;
131   Env env{handle_scope, argv};
132 
133   auto queue = reinterpret_cast<uintptr_t>((*env)->handle_wrap_queue());
134   auto head = queue +
135       nodedbg_offset_Environment_HandleWrapQueue__head___ListNode_HandleWrap;
136   auto tail = head + nodedbg_offset_ListNode_HandleWrap__prev___uintptr_t;
137   tail = *reinterpret_cast<uintptr_t*>(tail);
138 
139   uv_tcp_t handle;
140 
141   auto obj_template = v8::FunctionTemplate::New(isolate_);
142   obj_template->InstanceTemplate()->SetInternalFieldCount(1);
143 
144   v8::Local<v8::Object> object = obj_template->GetFunction(env.context())
145                                      .ToLocalChecked()
146                                      ->NewInstance(env.context())
147                                      .ToLocalChecked();
148   TestHandleWrap obj(*env, object, &handle);
149 
150   auto last = tail + nodedbg_offset_ListNode_HandleWrap__next___uintptr_t;
151   last = *reinterpret_cast<uintptr_t*>(last);
152 
153   auto expected = reinterpret_cast<uintptr_t>(&obj);
154   auto calculated =
155       last - nodedbg_offset_HandleWrap__handle_wrap_queue___ListNode_HandleWrap;
156   EXPECT_EQ(expected, calculated);
157 
158   obj.persistent().Reset();  // ~HandleWrap() expects an empty handle.
159 }
160 
TEST_F(DebugSymbolsTest,ReqWrapList)161 TEST_F(DebugSymbolsTest, ReqWrapList) {
162   const v8::HandleScope handle_scope(isolate_);
163   const Argv argv;
164   Env env{handle_scope, argv};
165 
166   auto queue = reinterpret_cast<uintptr_t>((*env)->req_wrap_queue());
167   auto head =
168       queue +
169       nodedbg_offset_Environment_ReqWrapQueue__head___ListNode_ReqWrapQueue;
170   auto tail = head + nodedbg_offset_ListNode_ReqWrap__prev___uintptr_t;
171   tail = *reinterpret_cast<uintptr_t*>(tail);
172 
173   auto obj_template = v8::FunctionTemplate::New(isolate_);
174   obj_template->InstanceTemplate()->SetInternalFieldCount(1);
175 
176   v8::Local<v8::Object> object = obj_template->GetFunction(env.context())
177                                      .ToLocalChecked()
178                                      ->NewInstance(env.context())
179                                      .ToLocalChecked();
180   TestReqWrap obj(*env, object);
181 
182   // NOTE (mmarchini): Workaround to fix failing tests on ARM64 machines with
183   // older GCC. Should be removed once we upgrade the GCC version used on our
184   // ARM64 CI machinies.
185   for (auto it : *(*env)->req_wrap_queue()) (void) &it;
186 
187   auto last = tail + nodedbg_offset_ListNode_ReqWrap__next___uintptr_t;
188   last = *reinterpret_cast<uintptr_t*>(last);
189 
190   auto expected = reinterpret_cast<uintptr_t>(&obj);
191   auto calculated =
192       last - nodedbg_offset_ReqWrap__req_wrap_queue___ListNode_ReqWrapQueue;
193   EXPECT_EQ(expected, calculated);
194 
195   obj.Dispatched();
196 }
197