Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(196)

Side by Side Diff: util/mach/symbolic_constants_mach_test.cc

Issue 563383002: Add SymbolicConstantsMach and its test (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Crashpad Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "util/mach/symbolic_constants_mach.h"
16
17 #include <mach/mach.h>
18 #include <string.h>
19
20 #include "base/basictypes.h"
21 #include "base/strings/string_piece.h"
22 #include "base/strings/stringprintf.h"
23 #include "gtest/gtest.h"
24 #include "util/mach/mach_extensions.h"
25
26 namespace {
27
28 using namespace crashpad;
29
30 // If expect is NULL, the conversion is expected to fail. If expect is empty,
Robert Sesek 2014/09/15 23:00:16 Use |expect| so that it's clear you're talking abo
31 // the conversion is expected to succeed, but the precise returned string value
32 // is unknown. Otherwise, the conversion is expected to succeed, and expect
33 // contains the precise expected string value to be returned. If expect contains
34 // the substring "0x1", the conversion is expected only to succeed when
35 // kUnknownIsNumeric is set.
36 //
37 // Only set kUseFullName or kUseShortName when calling this. Other options are
38 // exercised directly by this function.
39 template <typename Traits>
40 void TestSomethingToStringOnce(typename Traits::ValueType value,
41 const char* expect,
42 SymbolicConstantToStringOptions options) {
43 std::string actual =
44 Traits::SomethingToString(value, options | kUnknownIsEmpty | kUseOr);
45 std::string actual_numeric =
46 Traits::SomethingToString(value, options | kUnknownIsNumeric | kUseOr);
47 if (expect) {
48 if (expect[0] == '\0') {
49 EXPECT_FALSE(actual.empty()) << Traits::kValueName << " " << value;
50 } else if (strstr(expect, "0x1")) {
51 EXPECT_TRUE(actual.empty()) << Traits::kValueName << " " << value
52 << ", actual " << actual;
53 actual.assign(expect);
54 } else {
55 EXPECT_EQ(expect, actual) << Traits::kValueName << " " << value;
56 }
57 EXPECT_EQ(actual, actual_numeric) << Traits::kValueName << " " << value;
58 } else {
59 EXPECT_TRUE(actual.empty()) << Traits::kValueName << " " << value
60 << ", actual " << actual;
61 EXPECT_FALSE(actual_numeric.empty()) << Traits::kValueName << " " << value
62 << ", actual_numeric "
63 << actual_numeric;
64 }
65 }
66
67 template <typename Traits>
68 void TestSomethingToString(typename Traits::ValueType value,
69 const char* expect_full,
70 const char* expect_short) {
71 {
72 SCOPED_TRACE("full_name");
73 TestSomethingToStringOnce<Traits>(value, expect_full, kUseFullName);
74 }
75
76 {
77 SCOPED_TRACE("short_name");
78 TestSomethingToStringOnce<Traits>(value, expect_short, kUseShortName);
79 }
80 }
81
82 template <typename Traits>
83 void TestStringToSomething(const base::StringPiece& string,
84 StringToSymbolicConstantOptions options,
85 bool expect_result,
86 typename Traits::ValueType expect_value) {
87 typename Traits::ValueType actual_value;
88 bool actual_result =
89 Traits::StringToSomething(string, options, &actual_value);
90 if (expect_result) {
91 EXPECT_TRUE(actual_result) << "string " << string << ", options " << options
92 << ", " << Traits::kValueName << " "
93 << expect_value;
94 if (actual_result) {
95 EXPECT_EQ(expect_value, actual_value) << "string " << string
96 << ", options " << options;
97 }
98 } else {
99 EXPECT_FALSE(actual_result) << "string " << string << ", options "
100 << options << ", " << Traits::kValueName << " "
101 << actual_value;
102 }
103 }
104
105 const struct {
106 exception_type_t exception;
107 const char* full_name;
108 const char* short_name;
109 } kExceptionTestData[] = {
110 {EXC_BAD_ACCESS, "EXC_BAD_ACCESS", "BAD_ACCESS"},
111 {EXC_BAD_INSTRUCTION, "EXC_BAD_INSTRUCTION", "BAD_INSTRUCTION"},
112 {EXC_ARITHMETIC, "EXC_ARITHMETIC", "ARITHMETIC"},
113 {EXC_EMULATION, "EXC_EMULATION", "EMULATION"},
114 {EXC_SOFTWARE, "EXC_SOFTWARE", "SOFTWARE"},
115 {EXC_MACH_SYSCALL, "EXC_MACH_SYSCALL", "MACH_SYSCALL"},
116 {EXC_RPC_ALERT, "EXC_RPC_ALERT", "RPC_ALERT"},
117 {EXC_CRASH, "EXC_CRASH", "CRASH"},
118 {EXC_RESOURCE, "EXC_RESOURCE", "RESOURCE"},
119 {EXC_GUARD, "EXC_GUARD", "GUARD"},
120 };
121
122 struct ConvertExceptionTraits {
123 typedef exception_type_t ValueType;
124 static std::string SomethingToString(
125 ValueType value,
126 SymbolicConstantToStringOptions options) {
127 return ExceptionToString(value, options);
128 }
129 static bool StringToSomething(const base::StringPiece& string,
130 StringToSymbolicConstantOptions options,
131 ValueType* value) {
132 return StringToException(string, options, value);
133 }
134 static const char kValueName[];
135 };
136 const char ConvertExceptionTraits::kValueName[] = "exception";
137
138 void TestExceptionToString(exception_type_t value,
139 const char* expect_full,
140 const char* expect_short) {
141 return TestSomethingToString<ConvertExceptionTraits>(
142 value, expect_full, expect_short);
143 }
144
145 TEST(SymbolicConstantsMach, ExceptionToString) {
146 for (size_t index = 0; index < arraysize(kExceptionTestData); ++index) {
147 SCOPED_TRACE(base::StringPrintf("index %zu", index));
148 TestExceptionToString(kExceptionTestData[index].exception,
149 kExceptionTestData[index].full_name,
150 kExceptionTestData[index].short_name);
151 }
152
153 for (exception_type_t exception = 0; exception < EXC_TYPES_COUNT + 8;
154 ++exception) {
155 SCOPED_TRACE(base::StringPrintf("exception %d", exception));
156 if (exception > 0 && exception < EXC_TYPES_COUNT) {
157 TestExceptionToString(exception, "", "");
158 } else {
159 TestExceptionToString(exception, NULL, NULL);
160 }
161 }
162 }
163
164 void TestStringToException(const base::StringPiece& string,
165 StringToSymbolicConstantOptions options,
166 bool expect_result,
167 exception_type_t expect_value) {
168 return TestStringToSomething<ConvertExceptionTraits>(
169 string, options, expect_result, expect_value);
170 }
171
172 TEST(SymbolicConstantsMach, StringToException) {
173 const StringToSymbolicConstantOptions kOptions[] = {
174 0,
175 kAllowFullName,
176 kAllowShortName,
177 kAllowFullName | kAllowShortName,
178 kAllowNumber,
179 kAllowFullName | kAllowNumber,
180 kAllowShortName | kAllowNumber,
181 kAllowFullName | kAllowShortName | kAllowNumber,
182 };
183
184 for (size_t option_index = 0; option_index < arraysize(kOptions);
185 ++option_index) {
186 SCOPED_TRACE(base::StringPrintf("option_index %zu", option_index));
187 StringToSymbolicConstantOptions options = kOptions[option_index];
188 for (size_t index = 0; index < arraysize(kExceptionTestData); ++index) {
189 SCOPED_TRACE(base::StringPrintf("index %zu", index));
190 exception_type_t exception = kExceptionTestData[index].exception;
191 {
192 SCOPED_TRACE("full_name");
193 TestStringToException(kExceptionTestData[index].full_name,
194 options,
195 options & kAllowFullName,
196 exception);
197 }
198 {
199 SCOPED_TRACE("short_name");
200 TestStringToException(kExceptionTestData[index].short_name,
201 options,
202 options & kAllowShortName,
203 exception);
204 }
205 {
206 SCOPED_TRACE("number");
207 std::string number_string = base::StringPrintf("%d", exception);
208 TestStringToException(
209 number_string, options, options & kAllowNumber, exception);
210 }
211 }
212
213 const char* const kNegativeTestData[] = {
214 "EXC_CRASH ",
215 " EXC_BAD_INSTRUCTION",
216 "CRASH ",
217 " BAD_INSTRUCTION",
218 "EXC_EXC_BAD_ACCESS",
219 "EXC_SOFTWARES",
220 "SOFTWARES",
221 "EXC_JUNK",
222 "random",
223 "",
224 };
225
226 for (size_t index = 0; index < arraysize(kNegativeTestData); ++index) {
227 SCOPED_TRACE(base::StringPrintf("index %zu", index));
228 TestStringToException(kNegativeTestData[index], options, false, 0);
229 }
230
231 const struct {
232 const char* string;
233 size_t length;
234 } kNULTestData[] = {
235 #define NUL_TEST_DATA(string) { string, arraysize(string) - 1 }
236 NUL_TEST_DATA("\0EXC_ARITHMETIC"),
237 NUL_TEST_DATA("EXC_\0ARITHMETIC"),
238 NUL_TEST_DATA("EXC_ARITH\0METIC"),
239 NUL_TEST_DATA("EXC_ARITHMETIC\0"),
240 NUL_TEST_DATA("\0ARITHMETIC"),
241 NUL_TEST_DATA("ARITH\0METIC"),
242 NUL_TEST_DATA("ARITHMETIC\0"),
243 NUL_TEST_DATA("\0003"),
244 NUL_TEST_DATA("3\0"),
245 NUL_TEST_DATA("1\0002"),
246 #undef NUL_TEST_DATA
247 };
248
249 for (size_t index = 0; index < arraysize(kNULTestData); ++index) {
250 SCOPED_TRACE(base::StringPrintf("index %zu", index));
251 base::StringPiece string(kNULTestData[index].string,
252 kNULTestData[index].length);
253 TestStringToException(string, options, false, 0);
254 }
255 }
256
257 // Ensure that a NUL is not required at the end of the string.
258 {
259 SCOPED_TRACE("trailing_NUL_full");
260 TestStringToException(base::StringPiece("EXC_BREAKPOINTED", 14),
261 kAllowFullName,
262 true,
263 EXC_BREAKPOINT);
264 }
265 {
266 SCOPED_TRACE("trailing_NUL_short");
267 TestStringToException(base::StringPiece("BREAKPOINTED", 10),
268 kAllowShortName,
269 true,
270 EXC_BREAKPOINT);
271 }
272 }
273
274 const struct {
275 exception_mask_t exception_mask;
276 const char* full_name;
277 const char* short_name;
278 } kExceptionMaskTestData[] = {
279 {EXC_MASK_BAD_ACCESS, "EXC_MASK_BAD_ACCESS", "BAD_ACCESS"},
280 {EXC_MASK_BAD_INSTRUCTION, "EXC_MASK_BAD_INSTRUCTION", "BAD_INSTRUCTION"},
281 {EXC_MASK_ARITHMETIC, "EXC_MASK_ARITHMETIC", "ARITHMETIC"},
282 {EXC_MASK_EMULATION, "EXC_MASK_EMULATION", "EMULATION"},
283 {EXC_MASK_SOFTWARE, "EXC_MASK_SOFTWARE", "SOFTWARE"},
284 {EXC_MASK_MACH_SYSCALL, "EXC_MASK_MACH_SYSCALL", "MACH_SYSCALL"},
285 {EXC_MASK_RPC_ALERT, "EXC_MASK_RPC_ALERT", "RPC_ALERT"},
286 {EXC_MASK_CRASH, "EXC_MASK_CRASH", "CRASH"},
287 {EXC_MASK_RESOURCE, "EXC_MASK_RESOURCE", "RESOURCE"},
288 {EXC_MASK_GUARD, "EXC_MASK_GUARD", "GUARD"},
Robert Sesek 2014/09/15 23:00:16 Will this compile on 10.6?
Mark Mentovai 2014/09/16 13:42:17 rsesek wrote:
289 {0x1, "0x1", "0x1"},
290 {EXC_MASK_CRASH | 0x1, "EXC_MASK_CRASH|0x1", "CRASH|0x1"},
291 {EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC |
292 EXC_MASK_EMULATION |
293 EXC_MASK_SOFTWARE |
294 EXC_MASK_BREAKPOINT |
295 EXC_MASK_SYSCALL |
296 EXC_MASK_MACH_SYSCALL |
297 EXC_MASK_RPC_ALERT,
298 "EXC_MASK_BAD_ACCESS|EXC_MASK_BAD_INSTRUCTION|EXC_MASK_ARITHMETIC|"
299 "EXC_MASK_EMULATION|EXC_MASK_SOFTWARE|EXC_MASK_BREAKPOINT|"
300 "EXC_MASK_SYSCALL|EXC_MASK_MACH_SYSCALL|EXC_MASK_RPC_ALERT",
301 "BAD_ACCESS|BAD_INSTRUCTION|ARITHMETIC|EMULATION|SOFTWARE|BREAKPOINT|"
302 "SYSCALL|MACH_SYSCALL|RPC_ALERT"},
303 {EXC_MASK_RESOURCE | EXC_MASK_GUARD,
304 "EXC_MASK_RESOURCE|EXC_MASK_GUARD",
305 "RESOURCE|GUARD"},
306 };
307
308 struct ConvertExceptionMaskTraits {
309 typedef exception_mask_t ValueType;
310 static std::string SomethingToString(
311 ValueType value,
312 SymbolicConstantToStringOptions options) {
313 return ExceptionMaskToString(value, options);
314 }
315 static bool StringToSomething(const base::StringPiece& string,
316 StringToSymbolicConstantOptions options,
317 ValueType* value) {
318 return StringToExceptionMask(string, options, value);
319 }
320 static const char kValueName[];
321 };
322 const char ConvertExceptionMaskTraits::kValueName[] = "exception_mask";
323
324 void TestExceptionMaskToString(exception_mask_t value,
325 const char* expect_full,
326 const char* expect_short) {
327 return TestSomethingToString<ConvertExceptionMaskTraits>(
328 value, expect_full, expect_short);
329 }
330
331 TEST(SymbolicConstantsMach, ExceptionMaskToString) {
332 for (size_t index = 0; index < arraysize(kExceptionMaskTestData); ++index) {
333 SCOPED_TRACE(base::StringPrintf("index %zu", index));
334 TestExceptionMaskToString(kExceptionMaskTestData[index].exception_mask,
335 kExceptionMaskTestData[index].full_name,
336 kExceptionMaskTestData[index].short_name);
337 }
338
339 // Test kUseOr handling.
340 EXPECT_TRUE(ExceptionMaskToString(EXC_MASK_CRASH | EXC_MASK_GUARD,
341 kUseFullName).empty());
342 EXPECT_TRUE(ExceptionMaskToString(EXC_MASK_CRASH | EXC_MASK_GUARD,
343 kUseShortName).empty());
344 EXPECT_EQ("0x1400",
345 ExceptionMaskToString(EXC_MASK_CRASH | EXC_MASK_GUARD,
346 kUseFullName | kUnknownIsNumeric));
347 EXPECT_EQ("0x1400",
348 ExceptionMaskToString(EXC_MASK_CRASH | EXC_MASK_GUARD,
349 kUseShortName | kUnknownIsNumeric));
350 EXPECT_EQ("EXC_MASK_CRASH|EXC_MASK_GUARD",
351 ExceptionMaskToString(EXC_MASK_CRASH | EXC_MASK_GUARD,
352 kUseFullName | kUseOr));
353 EXPECT_EQ("CRASH|GUARD",
354 ExceptionMaskToString(EXC_MASK_CRASH | EXC_MASK_GUARD,
355 kUseShortName | kUseOr));
356 }
357
358 void TestStringToExceptionMask(const base::StringPiece& string,
359 StringToSymbolicConstantOptions options,
360 bool expect_result,
361 exception_mask_t expect_value) {
362 return TestStringToSomething<ConvertExceptionMaskTraits>(
363 string, options, expect_result, expect_value);
364 }
365
366 TEST(SymbolicConstantsMach, StringToExceptionMask) {
367 const StringToSymbolicConstantOptions kOptions[] = {
368 0,
369 kAllowFullName,
370 kAllowShortName,
371 kAllowFullName | kAllowShortName,
372 kAllowNumber,
373 kAllowFullName | kAllowNumber,
374 kAllowShortName | kAllowNumber,
375 kAllowFullName | kAllowShortName | kAllowNumber,
376 kAllowOr,
377 kAllowFullName | kAllowOr,
378 kAllowShortName | kAllowOr,
379 kAllowFullName | kAllowShortName | kAllowOr,
380 kAllowNumber | kAllowOr,
381 kAllowFullName | kAllowNumber | kAllowOr,
382 kAllowShortName | kAllowNumber | kAllowOr,
383 kAllowFullName | kAllowShortName | kAllowNumber | kAllowOr,
384 };
385
386 for (size_t option_index = 0; option_index < arraysize(kOptions);
387 ++option_index) {
388 SCOPED_TRACE(base::StringPrintf("option_index %zu", option_index));
389 StringToSymbolicConstantOptions options = kOptions[option_index];
390 for (size_t index = 0; index < arraysize(kExceptionMaskTestData); ++index) {
391 SCOPED_TRACE(base::StringPrintf("index %zu", index));
392 exception_mask_t exception_mask =
393 kExceptionMaskTestData[index].exception_mask;
394 {
395 SCOPED_TRACE("full_name");
396 base::StringPiece full_name(kExceptionMaskTestData[index].full_name);
397 bool has_number = full_name.find("0x", 0) != base::StringPiece::npos;
398 bool has_or = full_name.find('|', 0) != base::StringPiece::npos;
399 bool allowed_characteristics =
400 (has_number ? (options & kAllowNumber) : true) &&
401 (has_or ? (options & kAllowOr) : true);
402 bool is_number = full_name.compare("0x1") == 0;
403 bool expect_valid =
404 ((options & kAllowFullName) && allowed_characteristics) ||
405 ((options & kAllowNumber) && is_number);
406 TestStringToExceptionMask(
407 full_name, options, expect_valid, exception_mask);
408 }
409 {
410 SCOPED_TRACE("short_name");
411 base::StringPiece short_name(kExceptionMaskTestData[index].short_name);
412 bool has_number = short_name.find("0x", 0) != base::StringPiece::npos;
413 bool has_or = short_name.find('|', 0) != base::StringPiece::npos;
414 bool allowed_characteristics =
415 (has_number ? (options & kAllowNumber) : true) &&
416 (has_or ? (options & kAllowOr) : true);
417 bool is_number = short_name.compare("0x1") == 0;
418 bool expect_valid =
419 ((options & kAllowShortName) && allowed_characteristics) ||
420 ((options & kAllowNumber) && is_number);
421 TestStringToExceptionMask(
422 short_name, options, expect_valid, exception_mask);
423 }
424 }
425
426 const char* const kNegativeTestData[] = {
427 "EXC_MASK_CRASH ",
428 " EXC_MASK_BAD_INSTRUCTION",
429 "EXC_MASK_EXC_MASK_BAD_ACCESS",
430 "EXC_MASK_SOFTWARES",
431 "EXC_MASK_JUNK",
432 "EXC_GUARD",
433 "EXC_ARITHMETIC|EXC_FAKE",
434 "ARITHMETIC|FAKE",
435 "FAKE|ARITHMETIC",
436 "EXC_FAKE|EXC_ARITHMETIC",
437 "random",
438 "",
439 };
440
441 for (size_t index = 0; index < arraysize(kNegativeTestData); ++index) {
442 SCOPED_TRACE(base::StringPrintf("index %zu", index));
443 TestStringToExceptionMask(kNegativeTestData[index], options, false, 0);
444 }
445
446 const struct {
447 const char* string;
448 size_t length;
449 } kNULTestData[] = {
450 #define NUL_TEST_DATA(string) { string, arraysize(string) - 1 }
Robert Sesek 2014/09/15 23:00:16 Promote this to a file-level #define ?
451 NUL_TEST_DATA("\0EXC_MASK_ARITHMETIC"),
452 NUL_TEST_DATA("EXC_\0MASK_ARITHMETIC"),
453 NUL_TEST_DATA("EXC_MASK_\0ARITHMETIC"),
454 NUL_TEST_DATA("EXC_MASK_ARITH\0METIC"),
455 NUL_TEST_DATA("EXC_MASK_ARITHMETIC\0"),
456 NUL_TEST_DATA("\0ARITHMETIC"),
457 NUL_TEST_DATA("ARITH\0METIC"),
458 NUL_TEST_DATA("ARITHMETIC\0"),
459 NUL_TEST_DATA("\0003"),
460 NUL_TEST_DATA("3\0"),
461 NUL_TEST_DATA("1\0002"),
462 NUL_TEST_DATA("EXC_MASK_ARITHMETIC\0|EXC_MASK_EMULATION"),
463 NUL_TEST_DATA("EXC_MASK_ARITHMETIC|\0EXC_MASK_EMULATION"),
464 NUL_TEST_DATA("ARITHMETIC\0|EMULATION"),
465 NUL_TEST_DATA("ARITHMETIC|\0EMULATION"),
466 #undef NUL_TEST_DATA
467 };
468
469 for (size_t index = 0; index < arraysize(kNULTestData); ++index) {
470 SCOPED_TRACE(base::StringPrintf("index %zu", index));
471 base::StringPiece string(kNULTestData[index].string,
472 kNULTestData[index].length);
473 TestStringToExceptionMask(string, options, false, 0);
474 }
475 }
476
477 const struct {
478 const char* string;
479 StringToSymbolicConstantOptions options;
480 exception_mask_t mask;
481 } kNonCanonicalTestData[] = {
482 {"EXC_MASK_ALL", kAllowFullName, ExcMaskAll()},
483 {"ALL", kAllowShortName, ExcMaskAll()},
484 {"EXC_MASK_ALL|EXC_MASK_CRASH",
485 kAllowFullName | kAllowOr,
486 ExcMaskAll() | EXC_MASK_CRASH},
487 {"ALL|CRASH",
488 kAllowShortName | kAllowOr,
489 ExcMaskAll() | EXC_MASK_CRASH},
490 {"EXC_MASK_BAD_INSTRUCTION|EXC_MASK_BAD_ACCESS",
491 kAllowFullName | kAllowOr,
492 EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION},
493 {"EMULATION|ARITHMETIC",
494 kAllowShortName | kAllowOr,
495 EXC_MASK_ARITHMETIC | EXC_MASK_EMULATION},
496 {"EXC_MASK_SOFTWARE|BREAKPOINT",
497 kAllowFullName | kAllowShortName | kAllowOr,
498 EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT},
499 {"SYSCALL|0x100",
500 kAllowShortName | kAllowNumber | kAllowOr,
501 EXC_MASK_SYSCALL | 0x100},
502 };
503
504 for (size_t index = 0; index < arraysize(kNonCanonicalTestData); ++index) {
505 SCOPED_TRACE(base::StringPrintf("index %zu", index));
506 TestStringToExceptionMask(kNonCanonicalTestData[index].string,
507 kNonCanonicalTestData[index].options,
508 true,
509 kNonCanonicalTestData[index].mask);
510 }
511
512 // Ensure that a NUL is not required at the end of the string.
513 {
514 SCOPED_TRACE("trailing_NUL_full");
515 TestStringToExceptionMask(base::StringPiece("EXC_MASK_BREAKPOINTED", 19),
516 kAllowFullName,
517 true,
518 EXC_MASK_BREAKPOINT);
519 }
520 {
521 SCOPED_TRACE("trailing_NUL_short");
522 TestStringToExceptionMask(base::StringPiece("BREAKPOINTED", 10),
523 kAllowShortName,
524 true,
525 EXC_MASK_BREAKPOINT);
526 }
527 }
528
529 const struct {
530 exception_behavior_t behavior;
531 const char* full_name;
532 const char* short_name;
533 } kExceptionBehaviorTestData[] = {
534 {EXCEPTION_DEFAULT, "EXCEPTION_DEFAULT", "DEFAULT"},
535 {EXCEPTION_STATE, "EXCEPTION_STATE", "STATE"},
536 {EXCEPTION_STATE_IDENTITY, "EXCEPTION_STATE_IDENTITY", "STATE_IDENTITY"},
537 {static_cast<exception_behavior_t>(EXCEPTION_DEFAULT |
538 MACH_EXCEPTION_CODES),
539 "EXCEPTION_DEFAULT|MACH_EXCEPTION_CODES",
540 "DEFAULT|MACH"},
541 {static_cast<exception_behavior_t>(EXCEPTION_STATE |
542 MACH_EXCEPTION_CODES),
543 "EXCEPTION_STATE|MACH_EXCEPTION_CODES",
544 "STATE|MACH"},
545 {static_cast<exception_behavior_t>(EXCEPTION_STATE_IDENTITY |
546 MACH_EXCEPTION_CODES),
547 "EXCEPTION_STATE_IDENTITY|MACH_EXCEPTION_CODES",
548 "STATE_IDENTITY|MACH"},
549 };
550
551 struct ConvertExceptionBehaviorTraits {
552 typedef exception_behavior_t ValueType;
553 static std::string SomethingToString(
554 ValueType value,
555 SymbolicConstantToStringOptions options) {
556 return ExceptionBehaviorToString(value, options);
557 }
558 static bool StringToSomething(const base::StringPiece& string,
559 StringToSymbolicConstantOptions options,
560 ValueType* value) {
561 return StringToExceptionBehavior(string, options, value);
562 }
563 static const char kValueName[];
564 };
565 const char ConvertExceptionBehaviorTraits::kValueName[] = "behavior";
566
567 void TestExceptionBehaviorToString(exception_behavior_t value,
568 const char* expect_full,
569 const char* expect_short) {
570 return TestSomethingToString<ConvertExceptionBehaviorTraits>(
571 value, expect_full, expect_short);
572 }
573
574 TEST(SymbolicConstantsMach, ExceptionBehaviorToString) {
575 for (size_t index = 0; index < arraysize(kExceptionBehaviorTestData);
576 ++index) {
577 SCOPED_TRACE(base::StringPrintf("index %zu", index));
578 TestExceptionBehaviorToString(kExceptionBehaviorTestData[index].behavior,
579 kExceptionBehaviorTestData[index].full_name,
580 kExceptionBehaviorTestData[index].short_name);
581 }
582
583 for (exception_behavior_t behavior = 0; behavior < 8; ++behavior) {
584 SCOPED_TRACE(base::StringPrintf("behavior %d", behavior));
585 exception_behavior_t behavior_mach = behavior | MACH_EXCEPTION_CODES;
586 if (behavior > 0 && behavior <= EXCEPTION_STATE_IDENTITY) {
587 TestExceptionBehaviorToString(behavior, "", "");
588 TestExceptionBehaviorToString(behavior_mach, "", "");
589 } else {
590 TestExceptionBehaviorToString(behavior, NULL, NULL);
591 TestExceptionBehaviorToString(behavior_mach, NULL, NULL);
592 }
593 }
594 }
595
596 void TestStringToExceptionBehavior(const base::StringPiece& string,
597 StringToSymbolicConstantOptions options,
598 bool expect_result,
599 exception_behavior_t expect_value) {
600 return TestStringToSomething<ConvertExceptionBehaviorTraits>(
601 string, options, expect_result, expect_value);
602 }
603
604 TEST(SymbolicConstantsMach, StringToExceptionBehavior) {
605 const StringToSymbolicConstantOptions kOptions[] = {
Robert Sesek 2014/09/15 23:00:16 Share this table across tests where they're the sa
606 0,
607 kAllowFullName,
608 kAllowShortName,
609 kAllowFullName | kAllowShortName,
610 kAllowNumber,
611 kAllowFullName | kAllowNumber,
612 kAllowShortName | kAllowNumber,
613 kAllowFullName | kAllowShortName | kAllowNumber,
614 };
615
616 for (size_t option_index = 0; option_index < arraysize(kOptions);
617 ++option_index) {
618 SCOPED_TRACE(base::StringPrintf("option_index %zu", option_index));
619 StringToSymbolicConstantOptions options = kOptions[option_index];
620 for (size_t index = 0; index < arraysize(kExceptionBehaviorTestData);
621 ++index) {
622 SCOPED_TRACE(base::StringPrintf("index %zu", index));
623 exception_behavior_t behavior =
624 kExceptionBehaviorTestData[index].behavior;
625 {
626 SCOPED_TRACE("full_name");
627 TestStringToExceptionBehavior(
628 kExceptionBehaviorTestData[index].full_name,
629 options,
630 options & kAllowFullName,
631 behavior);
632 }
633 {
634 SCOPED_TRACE("short_name");
635 TestStringToExceptionBehavior(
636 kExceptionBehaviorTestData[index].short_name,
637 options,
638 options & kAllowShortName,
639 behavior);
640 }
641 {
642 SCOPED_TRACE("number");
643 std::string number_string = base::StringPrintf("0x%x", behavior);
644 TestStringToExceptionBehavior(
645 number_string, options, options & kAllowNumber, behavior);
646 }
647 }
648
649 const char* const kNegativeTestData[] = {
650 "EXCEPTION_DEFAULT ",
651 " EXCEPTION_STATE",
652 "EXCEPTION_EXCEPTION_STATE_IDENTITY",
653 "EXCEPTION_DEFAULTS",
654 "EXCEPTION_JUNK",
655 "random",
656 "MACH_EXCEPTION_CODES",
657 "MACH",
658 "MACH_EXCEPTION_CODES|MACH_EXCEPTION_CODES",
659 "MACH_EXCEPTION_CODES|EXCEPTION_NONEXISTENT",
660 "MACH|junk",
661 "EXCEPTION_DEFAULT|EXCEPTION_STATE",
662 "1|2",
663 "",
664 };
665
666 for (size_t index = 0; index < arraysize(kNegativeTestData); ++index) {
667 SCOPED_TRACE(base::StringPrintf("index %zu", index));
668 TestStringToExceptionBehavior(
669 kNegativeTestData[index], options, false, 0);
670 }
671
672 const struct {
673 const char* string;
674 size_t length;
675 } kNULTestData[] = {
676 #define NUL_TEST_DATA(string) { string, arraysize(string) - 1 }
677 NUL_TEST_DATA("\0EXCEPTION_STATE_IDENTITY"),
678 NUL_TEST_DATA("EXCEPTION_\0STATE_IDENTITY"),
679 NUL_TEST_DATA("EXCEPTION_STATE\0_IDENTITY"),
680 NUL_TEST_DATA("EXCEPTION_STATE_IDENTITY\0"),
681 NUL_TEST_DATA("\0STATE_IDENTITY"),
682 NUL_TEST_DATA("STATE\0_IDENTITY"),
683 NUL_TEST_DATA("STATE_IDENTITY\0"),
684 NUL_TEST_DATA("\0003"),
685 NUL_TEST_DATA("3\0"),
686 NUL_TEST_DATA("0x8000000\0001"),
687 NUL_TEST_DATA("EXCEPTION_STATE_IDENTITY\0|MACH_EXCEPTION_CODES"),
688 NUL_TEST_DATA("EXCEPTION_STATE_IDENTITY|\0MACH_EXCEPTION_CODES"),
689 NUL_TEST_DATA("STATE_IDENTITY\0|MACH"),
690 NUL_TEST_DATA("STATE_IDENTITY|\0MACH"),
691 #undef NUL_TEST_DATA
692 };
693
694 for (size_t index = 0; index < arraysize(kNULTestData); ++index) {
695 SCOPED_TRACE(base::StringPrintf("index %zu", index));
696 base::StringPiece string(kNULTestData[index].string,
697 kNULTestData[index].length);
698 TestStringToExceptionBehavior(string, options, false, 0);
699 }
700 }
701
702 const struct {
703 const char* string;
704 StringToSymbolicConstantOptions options;
705 exception_behavior_t behavior;
706 } kNonCanonicalTestData[] = {
707 {"MACH_EXCEPTION_CODES|EXCEPTION_STATE_IDENTITY",
708 kAllowFullName,
709 static_cast<exception_behavior_t>(EXCEPTION_STATE_IDENTITY |
710 MACH_EXCEPTION_CODES)},
711 {"MACH|STATE_IDENTITY",
712 kAllowShortName,
713 static_cast<exception_behavior_t>(EXCEPTION_STATE_IDENTITY |
714 MACH_EXCEPTION_CODES)},
715 {"MACH_EXCEPTION_CODES|STATE",
716 kAllowFullName | kAllowShortName,
717 static_cast<exception_behavior_t>(EXCEPTION_STATE |
718 MACH_EXCEPTION_CODES)},
719 {"MACH|EXCEPTION_STATE",
720 kAllowFullName | kAllowShortName,
721 static_cast<exception_behavior_t>(EXCEPTION_STATE |
722 MACH_EXCEPTION_CODES)},
723 {"3|MACH_EXCEPTION_CODES",
724 kAllowFullName | kAllowNumber,
725 static_cast<exception_behavior_t>(MACH_EXCEPTION_CODES | 3)},
726 {"MACH|0x2",
727 kAllowShortName | kAllowNumber,
728 static_cast<exception_behavior_t>(MACH_EXCEPTION_CODES | 0x2)},
729 };
730
731 for (size_t index = 0; index < arraysize(kNonCanonicalTestData); ++index) {
732 SCOPED_TRACE(base::StringPrintf("index %zu", index));
733 TestStringToExceptionBehavior(kNonCanonicalTestData[index].string,
734 kNonCanonicalTestData[index].options,
735 true,
736 kNonCanonicalTestData[index].behavior);
737 }
738
739 // Ensure that a NUL is not required at the end of the string.
740 {
741 SCOPED_TRACE("trailing_NUL_full");
742 TestStringToExceptionBehavior(base::StringPiece("EXCEPTION_DEFAULTS", 17),
743 kAllowFullName,
744 true,
745 EXCEPTION_DEFAULT);
746 }
747 {
748 SCOPED_TRACE("trailing_NUL_short");
749 TestStringToExceptionBehavior(base::StringPiece("DEFAULTS", 7),
750 kAllowShortName,
751 true,
752 EXCEPTION_DEFAULT);
753 }
754 {
755 SCOPED_TRACE("trailing_NUL_full_mach");
756 base::StringPiece string("EXCEPTION_DEFAULT|MACH_EXCEPTION_CODESS", 38);
757 TestStringToExceptionBehavior(string,
758 kAllowFullName | kAllowOr,
759 true,
760 EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES);
761 }
762 {
763 SCOPED_TRACE("trailing_NUL_short_mach");
764 TestStringToExceptionBehavior(base::StringPiece("DEFAULT|MACH_", 12),
765 kAllowShortName | kAllowOr,
766 true,
767 EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES);
768 }
769 }
770
771 const struct {
772 thread_state_flavor_t flavor;
773 const char* full_name;
774 const char* short_name;
775 } kThreadStateFlavorTestData[] = {
776 {THREAD_STATE_NONE, "THREAD_STATE_NONE", "NONE"},
777 {THREAD_STATE_FLAVOR_LIST, "THREAD_STATE_FLAVOR_LIST", "FLAVOR_LIST"},
778 {THREAD_STATE_FLAVOR_LIST_NEW,
779 "THREAD_STATE_FLAVOR_LIST_NEW",
780 "FLAVOR_LIST_NEW"},
781 {THREAD_STATE_FLAVOR_LIST_10_9,
782 "THREAD_STATE_FLAVOR_LIST_10_9",
783 "FLAVOR_LIST_10_9"},
784 #if defined(__i386__) || defined(__x86_64__)
785 {x86_THREAD_STATE32, "x86_THREAD_STATE32", "THREAD32"},
786 {x86_FLOAT_STATE32, "x86_FLOAT_STATE32", "FLOAT32"},
787 {x86_EXCEPTION_STATE32, "x86_EXCEPTION_STATE32", "EXCEPTION32"},
788 {x86_THREAD_STATE64, "x86_THREAD_STATE64", "THREAD64"},
789 {x86_FLOAT_STATE64, "x86_FLOAT_STATE64", "FLOAT64"},
790 {x86_EXCEPTION_STATE64, "x86_EXCEPTION_STATE64", "EXCEPTION64"},
791 {x86_THREAD_STATE, "x86_THREAD_STATE", "THREAD"},
792 {x86_FLOAT_STATE, "x86_FLOAT_STATE", "FLOAT"},
793 {x86_EXCEPTION_STATE, "x86_EXCEPTION_STATE", "EXCEPTION"},
794 {x86_DEBUG_STATE32, "x86_DEBUG_STATE32", "DEBUG32"},
795 {x86_DEBUG_STATE64, "x86_DEBUG_STATE64", "DEBUG64"},
796 {x86_DEBUG_STATE, "x86_DEBUG_STATE", "DEBUG"},
797 {14, "x86_SAVED_STATE32", "SAVED32"},
798 {15, "x86_SAVED_STATE64", "SAVED64"},
799 {x86_AVX_STATE32, "x86_AVX_STATE32", "AVX32"},
800 {x86_AVX_STATE64, "x86_AVX_STATE64", "AVX64"},
801 {x86_AVX_STATE, "x86_AVX_STATE", "AVX"},
802 #elif defined(__ppc__) || defined(__ppc64__)
803 {PPC_THREAD_STATE, "PPC_THREAD_STATE", "THREAD"},
804 {PPC_FLOAT_STATE, "PPC_FLOAT_STATE", "FLOAT"},
805 {PPC_EXCEPTION_STATE, "PPC_EXCEPTION_STATE", "EXCEPTION"},
806 {PPC_VECTOR_STATE, "PPC_VECTOR_STATE", "VECTOR"},
807 {PPC_THREAD_STATE64, "PPC_THREAD_STATE64", "THREAD64"},
808 {PPC_EXCEPTION_STATE64, "PPC_EXCEPTION_STATE64", "EXCEPTION64"},
809 #elif defined(__arm__) || defined(__arm64__)
810 {ARM_THREAD_STATE, "ARM_THREAD_STATE", "THREAD"},
811 {ARM_VFP_STATE, "ARM_VFP_STATE", "VFP"},
812 {ARM_EXCEPTION_STATE, "ARM_EXCEPTION_STATE", "EXCEPTION"},
813 {ARM_DEBUG_STATE, "ARM_DEBUG_STATE", "DEBUG"},
814 {ARM_THREAD_STATE64, "ARM_THREAD_STATE64", "THREAD64"},
815 {ARM_EXCEPTION_STATE64, "ARM_EXCEPTION_STATE64", "EXCEPTION64"},
816 {ARM_THREAD_STATE32, "ARM_THREAD_STATE32", "THREAD32"},
817 {ARM_DEBUG_STATE32, "ARM_DEBUG_STATE32", "DEBUG32"},
818 {ARM_DEBUG_STATE64, "ARM_DEBUG_STATE64", "DEBUG64"},
819 {ARM_NEON_STATE, "ARM_NEON_STATE", "NEON"},
820 {ARM_NEON_STATE64, "ARM_NEON_STATE64", "NEON64"},
821 #endif
822 };
823
824 struct ConvertThreadStateFlavorTraits {
825 typedef thread_state_flavor_t ValueType;
826 static std::string SomethingToString(
827 ValueType value,
828 SymbolicConstantToStringOptions options) {
829 return ThreadStateFlavorToString(value, options);
830 }
831 static bool StringToSomething(const base::StringPiece& string,
832 StringToSymbolicConstantOptions options,
833 ValueType* value) {
834 return StringToThreadStateFlavor(string, options, value);
835 }
836 static const char kValueName[];
837 };
838 const char ConvertThreadStateFlavorTraits::kValueName[] = "flavor";
839
840 void TestThreadStateFlavorToString(exception_type_t value,
841 const char* expect_full,
842 const char* expect_short) {
843 return TestSomethingToString<ConvertThreadStateFlavorTraits>(
844 value, expect_full, expect_short);
845 }
846
847 TEST(SymbolicConstantsMach, ThreadStateFlavorToString) {
848 for (size_t index = 0; index < arraysize(kThreadStateFlavorTestData);
849 ++index) {
850 SCOPED_TRACE(base::StringPrintf("index %zu", index));
851 TestThreadStateFlavorToString(kThreadStateFlavorTestData[index].flavor,
852 kThreadStateFlavorTestData[index].full_name,
853 kThreadStateFlavorTestData[index].short_name);
854 }
855
856 for (thread_state_flavor_t flavor = 0; flavor < 136; ++flavor) {
857 SCOPED_TRACE(base::StringPrintf("flavor %d", flavor));
858 if (
859 #if defined(__i386__) || defined(__x86_64__)
860 flavor <= 18
861 #elif defined(__ppc__) || defined(__ppc64__)
862 flavor <= 7
863 #elif defined(__arm__) || defined(__arm64__)
864 (flavor <= 7 || flavor == 9 || (flavor >= 14 && flavor <= 17))
Robert Sesek 2014/09/15 23:00:16 Why use magic numbers here?
Mark Mentovai 2014/09/16 13:42:16 rsesek wrote:
865 #endif
866 ||
867 flavor == THREAD_STATE_FLAVOR_LIST_NEW ||
868 flavor == THREAD_STATE_FLAVOR_LIST_10_9) {
869 TestThreadStateFlavorToString(flavor, "", "");
870 } else {
871 TestThreadStateFlavorToString(flavor, NULL, NULL);
872 }
873 }
874 }
875
876 void TestStringToThreadStateFlavor(const base::StringPiece& string,
877 StringToSymbolicConstantOptions options,
878 bool expect_result,
879 thread_state_flavor_t expect_value) {
880 return TestStringToSomething<ConvertThreadStateFlavorTraits>(
881 string, options, expect_result, expect_value);
882 }
883
884 TEST(SymbolicConstantsMach, StringToThreadStateFlavor) {
885 const StringToSymbolicConstantOptions kOptions[] = {
886 0,
887 kAllowFullName,
888 kAllowShortName,
889 kAllowFullName | kAllowShortName,
890 kAllowNumber,
891 kAllowFullName | kAllowNumber,
892 kAllowShortName | kAllowNumber,
893 kAllowFullName | kAllowShortName | kAllowNumber,
894 };
895
896 for (size_t option_index = 0; option_index < arraysize(kOptions);
897 ++option_index) {
898 SCOPED_TRACE(base::StringPrintf("option_index %zu", option_index));
899 StringToSymbolicConstantOptions options = kOptions[option_index];
900 for (size_t index = 0; index < arraysize(kThreadStateFlavorTestData);
901 ++index) {
902 SCOPED_TRACE(base::StringPrintf("index %zu", index));
903 thread_state_flavor_t flavor = kThreadStateFlavorTestData[index].flavor;
904 {
905 SCOPED_TRACE("full_name");
906 TestStringToThreadStateFlavor(
907 kThreadStateFlavorTestData[index].full_name,
908 options,
909 options & kAllowFullName,
910 flavor);
911 }
912 {
913 SCOPED_TRACE("short_name");
914 TestStringToThreadStateFlavor(
915 kThreadStateFlavorTestData[index].short_name,
916 options,
917 options & kAllowShortName,
918 flavor);
919 }
920 {
921 SCOPED_TRACE("number");
922 std::string number_string = base::StringPrintf("%d", flavor);
923 TestStringToThreadStateFlavor(
924 number_string, options, options & kAllowNumber, flavor);
925 }
926 }
927
928 const char* const kNegativeTestData[] = {
929 "THREAD_STATE_NONE ",
930 " THREAD_STATE_NONE",
931 "NONE ",
932 " NONE",
933 "THREAD_STATE_THREAD_STATE_NONE",
934 "THREAD_STATE_NONE_AT_ALL",
935 "NONE_AT_ALL",
936 "THREAD_STATE_JUNK",
937 "JUNK",
938 "random",
939 " THREAD64",
940 "THREAD64 ",
941 "THREAD642",
942 "",
943 #if defined(__i386__) || defined(__x86_64__)
944 " x86_THREAD_STATE64",
945 "x86_THREAD_STATE64 ",
946 "x86_THREAD_STATE642",
947 "x86_JUNK",
948 "x86_JUNK_STATE32",
949 "PPC_THREAD_STATE",
950 "ARM_THREAD_STATE",
951 #elif defined(__ppc__) || defined(__ppc64__)
952 " PPC_THREAD_STATE64",
953 "PPC_THREAD_STATE64 ",
954 "PPC_THREAD_STATE642",
955 "PPC_JUNK",
956 "PPC_JUNK_STATE32",
957 "x86_THREAD_STATE",
958 "ARM_THREAD_STATE",
959 #elif defined(__arm__) || defined(__arm64__)
960 " ARM_THREAD_STATE64",
961 "ARM_THREAD_STATE64 ",
962 "ARM_THREAD_STATE642",
963 "ARM_JUNK",
964 "ARM_JUNK_STATE32",
965 "x86_THREAD_STATE",
966 "PPC_THREAD_STATE",
967 #endif
968 };
969
970 for (size_t index = 0; index < arraysize(kNegativeTestData); ++index) {
971 SCOPED_TRACE(base::StringPrintf("index %zu", index));
972 TestStringToThreadStateFlavor(
973 kNegativeTestData[index], options, false, 0);
974 }
975
976 const struct {
977 const char* string;
978 size_t length;
979 } kNULTestData[] = {
980 #define NUL_TEST_DATA(string) { string, arraysize(string) - 1 }
981 NUL_TEST_DATA("\0THREAD_STATE_NONE"),
982 NUL_TEST_DATA("THREAD_\0STATE_NONE"),
983 NUL_TEST_DATA("THREAD_STATE_\0NONE"),
984 NUL_TEST_DATA("THREAD_STATE_NO\0NE"),
985 NUL_TEST_DATA("THREAD_STATE_NONE\0"),
986 NUL_TEST_DATA("\0NONE"),
987 NUL_TEST_DATA("NO\0NE"),
988 NUL_TEST_DATA("NONE\0"),
989 NUL_TEST_DATA("\0THREAD_STATE_FLAVOR_LIST_NEW"),
990 NUL_TEST_DATA("THREAD_STATE_\0FLAVOR_LIST_NEW"),
991 NUL_TEST_DATA("THREAD_STATE_FLAVOR_LIST\0_NEW"),
992 NUL_TEST_DATA("THREAD_STATE_FLAVOR_LIST_NEW\0"),
993 NUL_TEST_DATA("\0FLAVOR_LIST_NEW"),
994 NUL_TEST_DATA("FLAVOR_LIST\0_NEW"),
995 NUL_TEST_DATA("FLAVOR_LIST_NEW\0"),
996 NUL_TEST_DATA("\0THREAD"),
997 NUL_TEST_DATA("THR\0EAD"),
998 NUL_TEST_DATA("THREAD\0"),
999 NUL_TEST_DATA("\0THREAD64"),
1000 NUL_TEST_DATA("THR\0EAD64"),
1001 NUL_TEST_DATA("THREAD\064"),
1002 NUL_TEST_DATA("THREAD64\0"),
1003 NUL_TEST_DATA("\0002"),
1004 NUL_TEST_DATA("2\0"),
1005 NUL_TEST_DATA("1\0002"),
1006 #if defined(__i386__) || defined(__x86_64__)
1007 NUL_TEST_DATA("\0x86_THREAD_STATE64"),
1008 NUL_TEST_DATA("x86\0_THREAD_STATE64"),
1009 NUL_TEST_DATA("x86_\0THREAD_STATE64"),
1010 NUL_TEST_DATA("x86_THR\0EAD_STATE64"),
1011 NUL_TEST_DATA("x86_THREAD\0_STATE64"),
1012 NUL_TEST_DATA("x86_THREAD_\0STATE64"),
1013 NUL_TEST_DATA("x86_THREAD_STA\0TE64"),
1014 NUL_TEST_DATA("x86_THREAD_STATE\00064"),
1015 NUL_TEST_DATA("x86_THREAD_STATE64\0"),
1016 #elif defined(__ppc__) || defined(__ppc64__)
1017 NUL_TEST_DATA("\0PPC_THREAD_STATE64"),
1018 NUL_TEST_DATA("PPC\0_THREAD_STATE64"),
1019 NUL_TEST_DATA("PPC_\0THREAD_STATE64"),
1020 NUL_TEST_DATA("PPC_THR\0EAD_STATE64"),
1021 NUL_TEST_DATA("PPC_THREAD\0_STATE64"),
1022 NUL_TEST_DATA("PPC_THREAD_\0STATE64"),
1023 NUL_TEST_DATA("PPC_THREAD_STA\0TE64"),
1024 NUL_TEST_DATA("PPC_THREAD_STATE\00064"),
1025 #elif defined(__arm__) || defined(__arm64__)
1026 NUL_TEST_DATA("\0ARM_THREAD_STATE64"),
1027 NUL_TEST_DATA("ARM\0_THREAD_STATE64"),
1028 NUL_TEST_DATA("ARM_\0THREAD_STATE64"),
1029 NUL_TEST_DATA("ARM_THR\0EAD_STATE64"),
1030 NUL_TEST_DATA("ARM_THREAD\0_STATE64"),
1031 NUL_TEST_DATA("ARM_THREAD_\0STATE64"),
1032 NUL_TEST_DATA("ARM_THREAD_STA\0TE64"),
1033 NUL_TEST_DATA("ARM_THREAD_STATE\00064"),
1034 #endif
1035 #undef NUL_TEST_DATA
1036 };
1037
1038 for (size_t index = 0; index < arraysize(kNULTestData); ++index) {
1039 SCOPED_TRACE(base::StringPrintf("index %zu", index));
1040 base::StringPiece string(kNULTestData[index].string,
1041 kNULTestData[index].length);
1042 TestStringToThreadStateFlavor(string, options, false, 0);
1043 }
1044 }
1045
1046 // Ensure that a NUL is not required at the end of the string.
1047 {
1048 SCOPED_TRACE("trailing_NUL_full");
1049 TestStringToThreadStateFlavor(base::StringPiece("THREAD_STATE_NONER", 17),
1050 kAllowFullName,
1051 true,
1052 THREAD_STATE_NONE);
1053 }
1054 {
1055 SCOPED_TRACE("trailing_NUL_short");
1056 TestStringToThreadStateFlavor(base::StringPiece("NONER", 4),
1057 kAllowShortName,
1058 true,
1059 THREAD_STATE_NONE);
1060 }
1061 {
1062 SCOPED_TRACE("trailing_NUL_full_new");
1063 base::StringPiece string("THREAD_STATE_FLAVOR_LIST_NEWS", 28);
1064 TestStringToThreadStateFlavor(
1065 string, kAllowFullName, true, THREAD_STATE_FLAVOR_LIST_NEW);
1066 }
1067 {
1068 SCOPED_TRACE("trailing_NUL_short_new");
1069 TestStringToThreadStateFlavor(base::StringPiece("FLAVOR_LIST_NEWS", 15),
1070 kAllowShortName,
1071 true,
1072 THREAD_STATE_FLAVOR_LIST_NEW);
1073 }
1074 }
1075
1076 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698