xref: /llvm-project/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp (revision 8c92c899c6f4a895d3ebe990b684e1c30df12bc7)
1 //===-- GDBRemoteCommunicationClientTest.cpp --------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 #include <future>
10 
11 #include "GDBRemoteTestUtils.h"
12 
13 #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h"
14 #include "lldb/Core/ModuleSpec.h"
15 #include "lldb/Target/MemoryRegionInfo.h"
16 #include "lldb/Utility/DataBuffer.h"
17 #include "lldb/Utility/StructuredData.h"
18 #include "lldb/Utility/TraceOptions.h"
19 #include "lldb/lldb-enumerations.h"
20 #include "llvm/ADT/ArrayRef.h"
21 #include "llvm/Testing/Support/Error.h"
22 
23 using namespace lldb_private::process_gdb_remote;
24 using namespace lldb_private;
25 using namespace lldb;
26 using namespace llvm;
27 
28 namespace {
29 
30 typedef GDBRemoteCommunication::PacketResult PacketResult;
31 
32 struct TestClient : public GDBRemoteCommunicationClient {
33   TestClient() { m_send_acks = false; }
34 };
35 
36 void Handle_QThreadSuffixSupported(MockServer &server, bool supported) {
37   StringExtractorGDBRemote request;
38   ASSERT_EQ(PacketResult::Success, server.GetPacket(request));
39   ASSERT_EQ("QThreadSuffixSupported", request.GetStringRef());
40   if (supported)
41     ASSERT_EQ(PacketResult::Success, server.SendOKResponse());
42   else
43     ASSERT_EQ(PacketResult::Success, server.SendUnimplementedResponse(nullptr));
44 }
45 
46 void HandlePacket(MockServer &server, StringRef expected, StringRef response) {
47   StringExtractorGDBRemote request;
48   ASSERT_EQ(PacketResult::Success, server.GetPacket(request));
49   ASSERT_EQ(expected, request.GetStringRef());
50   ASSERT_EQ(PacketResult::Success, server.SendPacket(response));
51 }
52 
53 uint8_t all_registers[] = {'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
54                            'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O'};
55 std::string all_registers_hex = "404142434445464748494a4b4c4d4e4f";
56 uint8_t one_register[] = {'A', 'B', 'C', 'D'};
57 std::string one_register_hex = "41424344";
58 
59 } // end anonymous namespace
60 
61 class GDBRemoteCommunicationClientTest : public GDBRemoteTest {
62 public:
63   void SetUp() override {
64     ASSERT_THAT_ERROR(Connect(client, server), llvm::Succeeded());
65   }
66 
67 protected:
68   TestClient client;
69   MockServer server;
70 };
71 
72 TEST_F(GDBRemoteCommunicationClientTest, WriteRegister) {
73   const lldb::tid_t tid = 0x47;
74   const uint32_t reg_num = 4;
75   std::future<bool> write_result = std::async(std::launch::async, [&] {
76     return client.WriteRegister(tid, reg_num, one_register);
77   });
78 
79   Handle_QThreadSuffixSupported(server, true);
80 
81   HandlePacket(server, "P4=" + one_register_hex + ";thread:0047;", "OK");
82   ASSERT_TRUE(write_result.get());
83 
84   write_result = std::async(std::launch::async, [&] {
85     return client.WriteAllRegisters(tid, all_registers);
86   });
87 
88   HandlePacket(server, "G" + all_registers_hex + ";thread:0047;", "OK");
89   ASSERT_TRUE(write_result.get());
90 }
91 
92 TEST_F(GDBRemoteCommunicationClientTest, WriteRegisterNoSuffix) {
93   const lldb::tid_t tid = 0x47;
94   const uint32_t reg_num = 4;
95   std::future<bool> write_result = std::async(std::launch::async, [&] {
96     return client.WriteRegister(tid, reg_num, one_register);
97   });
98 
99   Handle_QThreadSuffixSupported(server, false);
100   HandlePacket(server, "Hg47", "OK");
101   HandlePacket(server, "P4=" + one_register_hex, "OK");
102   ASSERT_TRUE(write_result.get());
103 
104   write_result = std::async(std::launch::async, [&] {
105     return client.WriteAllRegisters(tid, all_registers);
106   });
107 
108   HandlePacket(server, "G" + all_registers_hex, "OK");
109   ASSERT_TRUE(write_result.get());
110 }
111 
112 TEST_F(GDBRemoteCommunicationClientTest, ReadRegister) {
113   const lldb::tid_t tid = 0x47;
114   const uint32_t reg_num = 4;
115   std::future<bool> async_result = std::async(
116       std::launch::async, [&] { return client.GetpPacketSupported(tid); });
117   Handle_QThreadSuffixSupported(server, true);
118   HandlePacket(server, "p0;thread:0047;", one_register_hex);
119   ASSERT_TRUE(async_result.get());
120 
121   std::future<DataBufferSP> read_result = std::async(
122       std::launch::async, [&] { return client.ReadRegister(tid, reg_num); });
123   HandlePacket(server, "p4;thread:0047;", "41424344");
124   auto buffer_sp = read_result.get();
125   ASSERT_TRUE(bool(buffer_sp));
126   ASSERT_EQ(0,
127             memcmp(buffer_sp->GetBytes(), one_register, sizeof one_register));
128 
129   read_result = std::async(std::launch::async,
130                            [&] { return client.ReadAllRegisters(tid); });
131   HandlePacket(server, "g;thread:0047;", all_registers_hex);
132   buffer_sp = read_result.get();
133   ASSERT_TRUE(bool(buffer_sp));
134   ASSERT_EQ(0,
135             memcmp(buffer_sp->GetBytes(), all_registers, sizeof all_registers));
136 }
137 
138 TEST_F(GDBRemoteCommunicationClientTest, SaveRestoreRegistersNoSuffix) {
139   const lldb::tid_t tid = 0x47;
140   uint32_t save_id;
141   std::future<bool> async_result = std::async(std::launch::async, [&] {
142     return client.SaveRegisterState(tid, save_id);
143   });
144   Handle_QThreadSuffixSupported(server, false);
145   HandlePacket(server, "Hg47", "OK");
146   HandlePacket(server, "QSaveRegisterState", "1");
147   ASSERT_TRUE(async_result.get());
148   EXPECT_EQ(1u, save_id);
149 
150   async_result = std::async(std::launch::async, [&] {
151     return client.RestoreRegisterState(tid, save_id);
152   });
153   HandlePacket(server, "QRestoreRegisterState:1", "OK");
154   ASSERT_TRUE(async_result.get());
155 }
156 
157 TEST_F(GDBRemoteCommunicationClientTest, SyncThreadState) {
158   const lldb::tid_t tid = 0x47;
159   std::future<bool> async_result = std::async(
160       std::launch::async, [&] { return client.SyncThreadState(tid); });
161   HandlePacket(server, "qSyncThreadStateSupported", "OK");
162   HandlePacket(server, "QSyncThreadState:0047;", "OK");
163   ASSERT_TRUE(async_result.get());
164 }
165 
166 TEST_F(GDBRemoteCommunicationClientTest, GetModulesInfo) {
167   llvm::Triple triple("i386-pc-linux");
168 
169   FileSpec file_specs[] = {
170       FileSpec("/foo/bar.so", false, FileSpec::ePathSyntaxPosix),
171       FileSpec("/foo/baz.so", false, FileSpec::ePathSyntaxPosix),
172 
173       // This is a bit dodgy but we currently depend on GetModulesInfo not
174       // performing denormalization. It can go away once the users
175       // (DynamicLoaderPOSIXDYLD, at least) correctly set the path syntax for
176       // the FileSpecs they create.
177       FileSpec("/foo/baw.so", false, FileSpec::ePathSyntaxWindows),
178   };
179   std::future<llvm::Optional<std::vector<ModuleSpec>>> async_result =
180       std::async(std::launch::async,
181                  [&] { return client.GetModulesInfo(file_specs, triple); });
182   HandlePacket(
183       server, "jModulesInfo:["
184               R"({"file":"/foo/bar.so","triple":"i386-pc-linux"},)"
185               R"({"file":"/foo/baz.so","triple":"i386-pc-linux"},)"
186               R"({"file":"/foo/baw.so","triple":"i386-pc-linux"}])",
187       R"([{"uuid":"404142434445464748494a4b4c4d4e4f","triple":"i386-pc-linux",)"
188       R"("file_path":"/foo/bar.so","file_offset":0,"file_size":1234}]])");
189 
190   auto result = async_result.get();
191   ASSERT_TRUE(result.hasValue());
192   ASSERT_EQ(1u, result->size());
193   EXPECT_EQ("/foo/bar.so", result.getValue()[0].GetFileSpec().GetPath());
194   EXPECT_EQ(triple, result.getValue()[0].GetArchitecture().GetTriple());
195   EXPECT_EQ(UUID("@ABCDEFGHIJKLMNO", 16), result.getValue()[0].GetUUID());
196   EXPECT_EQ(0u, result.getValue()[0].GetObjectOffset());
197   EXPECT_EQ(1234u, result.getValue()[0].GetObjectSize());
198 }
199 
200 TEST_F(GDBRemoteCommunicationClientTest, GetModulesInfo_UUID20) {
201   llvm::Triple triple("i386-pc-linux");
202 
203   FileSpec file_spec("/foo/bar.so", false, FileSpec::ePathSyntaxPosix);
204   std::future<llvm::Optional<std::vector<ModuleSpec>>> async_result =
205       std::async(std::launch::async,
206                  [&] { return client.GetModulesInfo(file_spec, triple); });
207   HandlePacket(
208       server,
209       "jModulesInfo:["
210       R"({"file":"/foo/bar.so","triple":"i386-pc-linux"}])",
211       R"([{"uuid":"404142434445464748494a4b4c4d4e4f50515253","triple":"i386-pc-linux",)"
212       R"("file_path":"/foo/bar.so","file_offset":0,"file_size":1234}]])");
213 
214   auto result = async_result.get();
215   ASSERT_TRUE(result.hasValue());
216   ASSERT_EQ(1u, result->size());
217   EXPECT_EQ("/foo/bar.so", result.getValue()[0].GetFileSpec().GetPath());
218   EXPECT_EQ(triple, result.getValue()[0].GetArchitecture().GetTriple());
219   EXPECT_EQ(UUID("@ABCDEFGHIJKLMNOPQRS", 20), result.getValue()[0].GetUUID());
220   EXPECT_EQ(0u, result.getValue()[0].GetObjectOffset());
221   EXPECT_EQ(1234u, result.getValue()[0].GetObjectSize());
222 }
223 
224 TEST_F(GDBRemoteCommunicationClientTest, GetModulesInfoInvalidResponse) {
225   llvm::Triple triple("i386-pc-linux");
226   FileSpec file_spec("/foo/bar.so", false, FileSpec::ePathSyntaxPosix);
227 
228   const char *invalid_responses[] = {
229       // no UUID
230       R"([{"triple":"i386-pc-linux",)"
231       R"("file_path":"/foo/bar.so","file_offset":0,"file_size":1234}]])",
232       // invalid UUID
233       R"([{"uuid":"XXXXXX","triple":"i386-pc-linux",)"
234       R"("file_path":"/foo/bar.so","file_offset":0,"file_size":1234}]])",
235       // no triple
236       R"([{"uuid":"404142434445464748494a4b4c4d4e4f",)"
237       R"("file_path":"/foo/bar.so","file_offset":0,"file_size":1234}]])",
238       // no file_path
239       R"([{"uuid":"404142434445464748494a4b4c4d4e4f","triple":"i386-pc-linux",)"
240       R"("file_offset":0,"file_size":1234}]])",
241       // no file_offset
242       R"([{"uuid":"404142434445464748494a4b4c4d4e4f","triple":"i386-pc-linux",)"
243       R"("file_path":"/foo/bar.so","file_size":1234}]])",
244       // no file_size
245       R"([{"uuid":"404142434445464748494a4b4c4d4e4f","triple":"i386-pc-linux",)"
246       R"("file_path":"/foo/bar.so","file_offset":0}]])",
247   };
248 
249   for (const char *response : invalid_responses) {
250     std::future<llvm::Optional<std::vector<ModuleSpec>>> async_result =
251         std::async(std::launch::async,
252                    [&] { return client.GetModulesInfo(file_spec, triple); });
253     HandlePacket(
254         server,
255         R"(jModulesInfo:[{"file":"/foo/bar.so","triple":"i386-pc-linux"}])",
256         response);
257 
258     auto result = async_result.get();
259     ASSERT_TRUE(result);
260     ASSERT_EQ(0u, result->size()) << "response was: " << response;
261   }
262 }
263 
264 TEST_F(GDBRemoteCommunicationClientTest, TestPacketSpeedJSON) {
265   std::thread server_thread([this] {
266     for (;;) {
267       StringExtractorGDBRemote request;
268       PacketResult result = server.GetPacket(request);
269       if (result == PacketResult::ErrorDisconnected)
270         return;
271       ASSERT_EQ(PacketResult::Success, result);
272       StringRef ref = request.GetStringRef();
273       ASSERT_TRUE(ref.consume_front("qSpeedTest:response_size:"));
274       int size;
275       ASSERT_FALSE(ref.consumeInteger(10, size)) << "ref: " << ref;
276       std::string response(size, 'X');
277       ASSERT_EQ(PacketResult::Success, server.SendPacket(response));
278     }
279   });
280 
281   StreamString ss;
282   client.TestPacketSpeed(10, 32, 32, 4096, true, ss);
283   client.Disconnect();
284   server_thread.join();
285 
286   GTEST_LOG_(INFO) << "Formatted output: " << ss.GetData();
287   auto object_sp = StructuredData::ParseJSON(ss.GetString());
288   ASSERT_TRUE(bool(object_sp));
289   auto dict_sp = object_sp->GetAsDictionary();
290   ASSERT_TRUE(bool(dict_sp));
291 
292   object_sp = dict_sp->GetValueForKey("packet_speeds");
293   ASSERT_TRUE(bool(object_sp));
294   dict_sp = object_sp->GetAsDictionary();
295   ASSERT_TRUE(bool(dict_sp));
296 
297   int num_packets;
298   ASSERT_TRUE(dict_sp->GetValueForKeyAsInteger("num_packets", num_packets))
299       << ss.GetString();
300   ASSERT_EQ(10, num_packets);
301 }
302 
303 TEST_F(GDBRemoteCommunicationClientTest, SendSignalsToIgnore) {
304   std::future<Status> result = std::async(std::launch::async, [&] {
305     return client.SendSignalsToIgnore({2, 3, 5, 7, 0xB, 0xD, 0x11});
306   });
307 
308   HandlePacket(server, "QPassSignals:02;03;05;07;0b;0d;11", "OK");
309   EXPECT_TRUE(result.get().Success());
310 
311   result = std::async(std::launch::async, [&] {
312     return client.SendSignalsToIgnore(std::vector<int32_t>());
313   });
314 
315   HandlePacket(server, "QPassSignals:", "OK");
316   EXPECT_TRUE(result.get().Success());
317 }
318 
319 TEST_F(GDBRemoteCommunicationClientTest, GetMemoryRegionInfo) {
320   const lldb::addr_t addr = 0xa000;
321   MemoryRegionInfo region_info;
322   std::future<Status> result = std::async(std::launch::async, [&] {
323     return client.GetMemoryRegionInfo(addr, region_info);
324   });
325 
326   // name is: /foo/bar.so
327   HandlePacket(server,
328       "qMemoryRegionInfo:a000",
329       "start:a000;size:2000;permissions:rx;name:2f666f6f2f6261722e736f;");
330   EXPECT_TRUE(result.get().Success());
331 
332 }
333 
334 TEST_F(GDBRemoteCommunicationClientTest, GetMemoryRegionInfoInvalidResponse) {
335   const lldb::addr_t addr = 0x4000;
336   MemoryRegionInfo region_info;
337   std::future<Status> result = std::async(std::launch::async, [&] {
338     return client.GetMemoryRegionInfo(addr, region_info);
339   });
340 
341   HandlePacket(server, "qMemoryRegionInfo:4000", "start:4000;size:0000;");
342   EXPECT_FALSE(result.get().Success());
343 }
344 
345 TEST_F(GDBRemoteCommunicationClientTest, SendStartTracePacket) {
346   TraceOptions options;
347   Status error;
348 
349   options.setType(lldb::TraceType::eTraceTypeProcessorTrace);
350   options.setMetaDataBufferSize(8192);
351   options.setTraceBufferSize(8192);
352   options.setThreadID(0x23);
353 
354   StructuredData::DictionarySP custom_params =
355       std::make_shared<StructuredData::Dictionary>();
356   custom_params->AddStringItem("tracetech", "intel-pt");
357   custom_params->AddIntegerItem("psb", 0x01);
358 
359   options.setTraceParams(custom_params);
360 
361   std::future<lldb::user_id_t> result = std::async(std::launch::async, [&] {
362     return client.SendStartTracePacket(options, error);
363   });
364 
365   // Since the line is exceeding 80 characters.
366   std::string expected_packet1 =
367       R"(jTraceStart:{"buffersize" : 8192,"metabuffersize" : 8192,"params" :)";
368   std::string expected_packet2 =
369       R"( {"psb" : 1,"tracetech" : "intel-pt"},"threadid" : 35,"type" : 1})";
370   HandlePacket(server, (expected_packet1 + expected_packet2), "1");
371   ASSERT_TRUE(error.Success());
372   ASSERT_EQ(result.get(), 1u);
373 
374   error.Clear();
375   result = std::async(std::launch::async, [&] {
376     return client.SendStartTracePacket(options, error);
377   });
378 
379   HandlePacket(server, (expected_packet1 + expected_packet2), "E23");
380   ASSERT_EQ(result.get(), LLDB_INVALID_UID);
381   ASSERT_FALSE(error.Success());
382 }
383 
384 TEST_F(GDBRemoteCommunicationClientTest, SendStopTracePacket) {
385   lldb::tid_t thread_id = 0x23;
386   lldb::user_id_t trace_id = 3;
387 
388   std::future<Status> result = std::async(std::launch::async, [&] {
389     return client.SendStopTracePacket(trace_id, thread_id);
390   });
391 
392   const char *expected_packet =
393       R"(jTraceStop:{"threadid" : 35,"traceid" : 3})";
394   HandlePacket(server, expected_packet, "OK");
395   ASSERT_TRUE(result.get().Success());
396 
397   result = std::async(std::launch::async, [&] {
398     return client.SendStopTracePacket(trace_id, thread_id);
399   });
400 
401   HandlePacket(server, expected_packet, "E23");
402   ASSERT_FALSE(result.get().Success());
403 }
404 
405 TEST_F(GDBRemoteCommunicationClientTest, SendGetDataPacket) {
406   lldb::tid_t thread_id = 0x23;
407   lldb::user_id_t trace_id = 3;
408 
409   uint8_t buf[32] = {};
410   llvm::MutableArrayRef<uint8_t> buffer(buf, 32);
411   size_t offset = 0;
412 
413   std::future<Status> result = std::async(std::launch::async, [&] {
414     return client.SendGetDataPacket(trace_id, thread_id, buffer, offset);
415   });
416 
417   std::string expected_packet1 =
418       R"(jTraceBufferRead:{"buffersize" : 32,"offset" : 0,"threadid" : 35,)";
419   std::string expected_packet2 = R"("traceid" : 3})";
420   HandlePacket(server, expected_packet1+expected_packet2, "123456");
421   ASSERT_TRUE(result.get().Success());
422   ASSERT_EQ(buffer.size(), 3u);
423   ASSERT_EQ(buf[0], 0x12);
424   ASSERT_EQ(buf[1], 0x34);
425   ASSERT_EQ(buf[2], 0x56);
426 
427   llvm::MutableArrayRef<uint8_t> buffer2(buf, 32);
428   result = std::async(std::launch::async, [&] {
429     return client.SendGetDataPacket(trace_id, thread_id, buffer2, offset);
430   });
431 
432   HandlePacket(server, expected_packet1+expected_packet2, "E23");
433   ASSERT_FALSE(result.get().Success());
434   ASSERT_EQ(buffer2.size(), 0u);
435 }
436 
437 TEST_F(GDBRemoteCommunicationClientTest, SendGetMetaDataPacket) {
438   lldb::tid_t thread_id = 0x23;
439   lldb::user_id_t trace_id = 3;
440 
441   uint8_t buf[32] = {};
442   llvm::MutableArrayRef<uint8_t> buffer(buf, 32);
443   size_t offset = 0;
444 
445   std::future<Status> result = std::async(std::launch::async, [&] {
446     return client.SendGetMetaDataPacket(trace_id, thread_id, buffer, offset);
447   });
448 
449   std::string expected_packet1 =
450       R"(jTraceMetaRead:{"buffersize" : 32,"offset" : 0,"threadid" : 35,)";
451   std::string expected_packet2 = R"("traceid" : 3})";
452   HandlePacket(server, expected_packet1+expected_packet2, "123456");
453   ASSERT_TRUE(result.get().Success());
454   ASSERT_EQ(buffer.size(), 3u);
455   ASSERT_EQ(buf[0], 0x12);
456   ASSERT_EQ(buf[1], 0x34);
457   ASSERT_EQ(buf[2], 0x56);
458 
459   llvm::MutableArrayRef<uint8_t> buffer2(buf, 32);
460   result = std::async(std::launch::async, [&] {
461     return client.SendGetMetaDataPacket(trace_id, thread_id, buffer2, offset);
462   });
463 
464   HandlePacket(server, expected_packet1+expected_packet2, "E23");
465   ASSERT_FALSE(result.get().Success());
466   ASSERT_EQ(buffer2.size(), 0u);
467 }
468 
469 TEST_F(GDBRemoteCommunicationClientTest, SendGetTraceConfigPacket) {
470   lldb::tid_t thread_id = 0x23;
471   lldb::user_id_t trace_id = 3;
472   TraceOptions options;
473   options.setThreadID(thread_id);
474 
475   std::future<Status> result = std::async(std::launch::async, [&] {
476     return client.SendGetTraceConfigPacket(trace_id, options);
477   });
478 
479   const char *expected_packet =
480       R"(jTraceConfigRead:{"threadid" : 35,"traceid" : 3})";
481   std::string response1 =
482       R"({"buffersize" : 8192,"params" : {"psb" : 1,"tracetech" : "intel-pt"})";
483   std::string response2 =
484       R"(],"metabuffersize" : 8192,"threadid" : 35,"type" : 1}])";
485   HandlePacket(server, expected_packet, response1+response2);
486   ASSERT_TRUE(result.get().Success());
487   ASSERT_EQ(options.getTraceBufferSize(), 8192u);
488   ASSERT_EQ(options.getMetaDataBufferSize(), 8192u);
489   ASSERT_EQ(options.getType(), 1);
490 
491   auto custom_params = options.getTraceParams();
492 
493   uint64_t psb_value;
494   llvm::StringRef trace_tech_value;
495 
496   ASSERT_TRUE(custom_params);
497   ASSERT_EQ(custom_params->GetType(), eStructuredDataTypeDictionary);
498   ASSERT_TRUE(custom_params->GetValueForKeyAsInteger("psb", psb_value));
499   ASSERT_EQ(psb_value, 1u);
500   ASSERT_TRUE(
501       custom_params->GetValueForKeyAsString("tracetech", trace_tech_value));
502   ASSERT_STREQ(trace_tech_value.data(), "intel-pt");
503 
504   // Checking error response.
505   std::future<Status> result2 = std::async(std::launch::async, [&] {
506     return client.SendGetTraceConfigPacket(trace_id, options);
507   });
508 
509   HandlePacket(server, expected_packet, "E23");
510   ASSERT_FALSE(result2.get().Success());
511 
512   // Wrong JSON as response.
513   std::future<Status> result3 = std::async(std::launch::async, [&] {
514     return client.SendGetTraceConfigPacket(trace_id, options);
515   });
516 
517   std::string incorrect_json1 =
518       R"("buffersize" : 8192,"params" : {"psb" : 1,"tracetech" : "intel-pt"})";
519   std::string incorrect_json2 =
520       R"(],"metabuffersize" : 8192,"threadid" : 35,"type" : 1}])";
521   HandlePacket(server, expected_packet, incorrect_json1+incorrect_json2);
522   ASSERT_FALSE(result3.get().Success());
523 
524   // Wrong JSON as custom_params.
525   std::future<Status> result4 = std::async(std::launch::async, [&] {
526     return client.SendGetTraceConfigPacket(trace_id, options);
527   });
528 
529   std::string incorrect_custom_params1 =
530       R"({"buffersize" : 8192,"params" : "psb" : 1,"tracetech" : "intel-pt"})";
531   std::string incorrect_custom_params2 =
532       R"(],"metabuffersize" : 8192,"threadid" : 35,"type" : 1}])";
533   HandlePacket(server, expected_packet, incorrect_custom_params1+
534       incorrect_custom_params2);
535   ASSERT_FALSE(result4.get().Success());
536 }
537