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

Unified 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: Rebase 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « util/mach/symbolic_constants_mach.cc ('k') | util/posix/symbolic_constants_posix_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: util/mach/symbolic_constants_mach_test.cc
diff --git a/util/mach/symbolic_constants_mach_test.cc b/util/mach/symbolic_constants_mach_test.cc
new file mode 100644
index 0000000000000000000000000000000000000000..4bc17c814c82dfb695a923e20343d323f3a86ab2
--- /dev/null
+++ b/util/mach/symbolic_constants_mach_test.cc
@@ -0,0 +1,1064 @@
+// Copyright 2014 The Crashpad Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "util/mach/symbolic_constants_mach.h"
+
+#include <mach/mach.h>
+#include <string.h>
+
+#include "base/basictypes.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/stringprintf.h"
+#include "gtest/gtest.h"
+#include "util/mach/mach_extensions.h"
+
+#define NUL_TEST_DATA(string) { string, arraysize(string) - 1 }
+
+namespace {
+
+using namespace crashpad;
+
+// Options to use for normal tests, those that don’t require kAllowOr.
+const StringToSymbolicConstantOptions kNormalOptions[] = {
+ 0,
+ kAllowFullName,
+ kAllowShortName,
+ kAllowFullName | kAllowShortName,
+ kAllowNumber,
+ kAllowFullName | kAllowNumber,
+ kAllowShortName | kAllowNumber,
+ kAllowFullName | kAllowShortName | kAllowNumber,
+};
+
+// If |expect| is NULL, the conversion is expected to fail. If |expect| is
+// empty, the conversion is expected to succeed, but the precise returned string
+// value is unknown. Otherwise, the conversion is expected to succeed, and
+// |expect| contains the precise expected string value to be returned. If
+// |expect| contains the substring "0x1", the conversion is expected only to
+// succeed when kUnknownIsNumeric is set.
+//
+// Only set kUseFullName or kUseShortName when calling this. Other options are
+// exercised directly by this function.
+template <typename Traits>
+void TestSomethingToStringOnce(typename Traits::ValueType value,
+ const char* expect,
+ SymbolicConstantToStringOptions options) {
+ std::string actual =
+ Traits::SomethingToString(value, options | kUnknownIsEmpty | kUseOr);
+ std::string actual_numeric =
+ Traits::SomethingToString(value, options | kUnknownIsNumeric | kUseOr);
+ if (expect) {
+ if (expect[0] == '\0') {
+ EXPECT_FALSE(actual.empty()) << Traits::kValueName << " " << value;
+ } else if (strstr(expect, "0x1")) {
+ EXPECT_TRUE(actual.empty()) << Traits::kValueName << " " << value
+ << ", actual " << actual;
+ actual.assign(expect);
+ } else {
+ EXPECT_EQ(expect, actual) << Traits::kValueName << " " << value;
+ }
+ EXPECT_EQ(actual, actual_numeric) << Traits::kValueName << " " << value;
+ } else {
+ EXPECT_TRUE(actual.empty()) << Traits::kValueName << " " << value
+ << ", actual " << actual;
+ EXPECT_FALSE(actual_numeric.empty()) << Traits::kValueName << " " << value
+ << ", actual_numeric "
+ << actual_numeric;
+ }
+}
+
+template <typename Traits>
+void TestSomethingToString(typename Traits::ValueType value,
+ const char* expect_full,
+ const char* expect_short) {
+ {
+ SCOPED_TRACE("full_name");
+ TestSomethingToStringOnce<Traits>(value, expect_full, kUseFullName);
+ }
+
+ {
+ SCOPED_TRACE("short_name");
+ TestSomethingToStringOnce<Traits>(value, expect_short, kUseShortName);
+ }
+}
+
+template <typename Traits>
+void TestStringToSomething(const base::StringPiece& string,
+ StringToSymbolicConstantOptions options,
+ bool expect_result,
+ typename Traits::ValueType expect_value) {
+ typename Traits::ValueType actual_value;
+ bool actual_result =
+ Traits::StringToSomething(string, options, &actual_value);
+ if (expect_result) {
+ EXPECT_TRUE(actual_result) << "string " << string << ", options " << options
+ << ", " << Traits::kValueName << " "
+ << expect_value;
+ if (actual_result) {
+ EXPECT_EQ(expect_value, actual_value) << "string " << string
+ << ", options " << options;
+ }
+ } else {
+ EXPECT_FALSE(actual_result) << "string " << string << ", options "
+ << options << ", " << Traits::kValueName << " "
+ << actual_value;
+ }
+}
+
+const struct {
+ exception_type_t exception;
+ const char* full_name;
+ const char* short_name;
+} kExceptionTestData[] = {
+ {EXC_BAD_ACCESS, "EXC_BAD_ACCESS", "BAD_ACCESS"},
+ {EXC_BAD_INSTRUCTION, "EXC_BAD_INSTRUCTION", "BAD_INSTRUCTION"},
+ {EXC_ARITHMETIC, "EXC_ARITHMETIC", "ARITHMETIC"},
+ {EXC_EMULATION, "EXC_EMULATION", "EMULATION"},
+ {EXC_SOFTWARE, "EXC_SOFTWARE", "SOFTWARE"},
+ {EXC_MACH_SYSCALL, "EXC_MACH_SYSCALL", "MACH_SYSCALL"},
+ {EXC_RPC_ALERT, "EXC_RPC_ALERT", "RPC_ALERT"},
+ {EXC_CRASH, "EXC_CRASH", "CRASH"},
+ {EXC_RESOURCE, "EXC_RESOURCE", "RESOURCE"},
+ {EXC_GUARD, "EXC_GUARD", "GUARD"},
+};
+
+struct ConvertExceptionTraits {
+ typedef exception_type_t ValueType;
+ static std::string SomethingToString(
+ ValueType value,
+ SymbolicConstantToStringOptions options) {
+ return ExceptionToString(value, options);
+ }
+ static bool StringToSomething(const base::StringPiece& string,
+ StringToSymbolicConstantOptions options,
+ ValueType* value) {
+ return StringToException(string, options, value);
+ }
+ static const char kValueName[];
+};
+const char ConvertExceptionTraits::kValueName[] = "exception";
+
+void TestExceptionToString(exception_type_t value,
+ const char* expect_full,
+ const char* expect_short) {
+ return TestSomethingToString<ConvertExceptionTraits>(
+ value, expect_full, expect_short);
+}
+
+TEST(SymbolicConstantsMach, ExceptionToString) {
+ for (size_t index = 0; index < arraysize(kExceptionTestData); ++index) {
+ SCOPED_TRACE(base::StringPrintf("index %zu", index));
+ TestExceptionToString(kExceptionTestData[index].exception,
+ kExceptionTestData[index].full_name,
+ kExceptionTestData[index].short_name);
+ }
+
+ for (exception_type_t exception = 0;
+ exception < EXC_TYPES_COUNT + 8;
+ ++exception) {
+ SCOPED_TRACE(base::StringPrintf("exception %d", exception));
+ if (exception > 0 && exception < EXC_TYPES_COUNT) {
+ TestExceptionToString(exception, "", "");
+ } else {
+ TestExceptionToString(exception, NULL, NULL);
+ }
+ }
+}
+
+void TestStringToException(const base::StringPiece& string,
+ StringToSymbolicConstantOptions options,
+ bool expect_result,
+ exception_type_t expect_value) {
+ return TestStringToSomething<ConvertExceptionTraits>(
+ string, options, expect_result, expect_value);
+}
+
+TEST(SymbolicConstantsMach, StringToException) {
+ for (size_t option_index = 0;
+ option_index < arraysize(kNormalOptions);
+ ++option_index) {
+ SCOPED_TRACE(base::StringPrintf("option_index %zu", option_index));
+ StringToSymbolicConstantOptions options = kNormalOptions[option_index];
+ for (size_t index = 0; index < arraysize(kExceptionTestData); ++index) {
+ SCOPED_TRACE(base::StringPrintf("index %zu", index));
+ exception_type_t exception = kExceptionTestData[index].exception;
+ {
+ SCOPED_TRACE("full_name");
+ TestStringToException(kExceptionTestData[index].full_name,
+ options,
+ options & kAllowFullName,
+ exception);
+ }
+ {
+ SCOPED_TRACE("short_name");
+ TestStringToException(kExceptionTestData[index].short_name,
+ options,
+ options & kAllowShortName,
+ exception);
+ }
+ {
+ SCOPED_TRACE("number");
+ std::string number_string = base::StringPrintf("%d", exception);
+ TestStringToException(
+ number_string, options, options & kAllowNumber, exception);
+ }
+ }
+
+ const char* const kNegativeTestData[] = {
+ "EXC_CRASH ",
+ " EXC_BAD_INSTRUCTION",
+ "CRASH ",
+ " BAD_INSTRUCTION",
+ "EXC_EXC_BAD_ACCESS",
+ "EXC_SOFTWARES",
+ "SOFTWARES",
+ "EXC_JUNK",
+ "random",
+ "",
+ };
+
+ for (size_t index = 0; index < arraysize(kNegativeTestData); ++index) {
+ SCOPED_TRACE(base::StringPrintf("index %zu", index));
+ TestStringToException(kNegativeTestData[index], options, false, 0);
+ }
+
+ const struct {
+ const char* string;
+ size_t length;
+ } kNULTestData[] = {
+ NUL_TEST_DATA("\0EXC_ARITHMETIC"),
+ NUL_TEST_DATA("EXC_\0ARITHMETIC"),
+ NUL_TEST_DATA("EXC_ARITH\0METIC"),
+ NUL_TEST_DATA("EXC_ARITHMETIC\0"),
+ NUL_TEST_DATA("\0ARITHMETIC"),
+ NUL_TEST_DATA("ARITH\0METIC"),
+ NUL_TEST_DATA("ARITHMETIC\0"),
+ NUL_TEST_DATA("\0003"),
+ NUL_TEST_DATA("3\0"),
+ NUL_TEST_DATA("1\0002"),
+ };
+
+ for (size_t index = 0; index < arraysize(kNULTestData); ++index) {
+ SCOPED_TRACE(base::StringPrintf("index %zu", index));
+ base::StringPiece string(kNULTestData[index].string,
+ kNULTestData[index].length);
+ TestStringToException(string, options, false, 0);
+ }
+ }
+
+ // Ensure that a NUL is not required at the end of the string.
+ {
+ SCOPED_TRACE("trailing_NUL_full");
+ TestStringToException(base::StringPiece("EXC_BREAKPOINTED", 14),
+ kAllowFullName,
+ true,
+ EXC_BREAKPOINT);
+ }
+ {
+ SCOPED_TRACE("trailing_NUL_short");
+ TestStringToException(base::StringPiece("BREAKPOINTED", 10),
+ kAllowShortName,
+ true,
+ EXC_BREAKPOINT);
+ }
+}
+
+const struct {
+ exception_mask_t exception_mask;
+ const char* full_name;
+ const char* short_name;
+} kExceptionMaskTestData[] = {
+ {EXC_MASK_BAD_ACCESS, "EXC_MASK_BAD_ACCESS", "BAD_ACCESS"},
+ {EXC_MASK_BAD_INSTRUCTION, "EXC_MASK_BAD_INSTRUCTION", "BAD_INSTRUCTION"},
+ {EXC_MASK_ARITHMETIC, "EXC_MASK_ARITHMETIC", "ARITHMETIC"},
+ {EXC_MASK_EMULATION, "EXC_MASK_EMULATION", "EMULATION"},
+ {EXC_MASK_SOFTWARE, "EXC_MASK_SOFTWARE", "SOFTWARE"},
+ {EXC_MASK_MACH_SYSCALL, "EXC_MASK_MACH_SYSCALL", "MACH_SYSCALL"},
+ {EXC_MASK_RPC_ALERT, "EXC_MASK_RPC_ALERT", "RPC_ALERT"},
+ {EXC_MASK_CRASH, "EXC_MASK_CRASH", "CRASH"},
+ {EXC_MASK_RESOURCE, "EXC_MASK_RESOURCE", "RESOURCE"},
+ {EXC_MASK_GUARD, "EXC_MASK_GUARD", "GUARD"},
+ {0x1, "0x1", "0x1"},
+ {EXC_MASK_CRASH | 0x1, "EXC_MASK_CRASH|0x1", "CRASH|0x1"},
+ {EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC |
+ EXC_MASK_EMULATION |
+ EXC_MASK_SOFTWARE |
+ EXC_MASK_BREAKPOINT |
+ EXC_MASK_SYSCALL |
+ EXC_MASK_MACH_SYSCALL |
+ EXC_MASK_RPC_ALERT,
+ "EXC_MASK_BAD_ACCESS|EXC_MASK_BAD_INSTRUCTION|EXC_MASK_ARITHMETIC|"
+ "EXC_MASK_EMULATION|EXC_MASK_SOFTWARE|EXC_MASK_BREAKPOINT|"
+ "EXC_MASK_SYSCALL|EXC_MASK_MACH_SYSCALL|EXC_MASK_RPC_ALERT",
+ "BAD_ACCESS|BAD_INSTRUCTION|ARITHMETIC|EMULATION|SOFTWARE|BREAKPOINT|"
+ "SYSCALL|MACH_SYSCALL|RPC_ALERT"},
+ {EXC_MASK_RESOURCE | EXC_MASK_GUARD,
+ "EXC_MASK_RESOURCE|EXC_MASK_GUARD",
+ "RESOURCE|GUARD"},
+};
+
+struct ConvertExceptionMaskTraits {
+ typedef exception_mask_t ValueType;
+ static std::string SomethingToString(
+ ValueType value,
+ SymbolicConstantToStringOptions options) {
+ return ExceptionMaskToString(value, options);
+ }
+ static bool StringToSomething(const base::StringPiece& string,
+ StringToSymbolicConstantOptions options,
+ ValueType* value) {
+ return StringToExceptionMask(string, options, value);
+ }
+ static const char kValueName[];
+};
+const char ConvertExceptionMaskTraits::kValueName[] = "exception_mask";
+
+void TestExceptionMaskToString(exception_mask_t value,
+ const char* expect_full,
+ const char* expect_short) {
+ return TestSomethingToString<ConvertExceptionMaskTraits>(
+ value, expect_full, expect_short);
+}
+
+TEST(SymbolicConstantsMach, ExceptionMaskToString) {
+ for (size_t index = 0; index < arraysize(kExceptionMaskTestData); ++index) {
+ SCOPED_TRACE(base::StringPrintf("index %zu", index));
+ TestExceptionMaskToString(kExceptionMaskTestData[index].exception_mask,
+ kExceptionMaskTestData[index].full_name,
+ kExceptionMaskTestData[index].short_name);
+ }
+
+ // Test kUseOr handling.
+ EXPECT_TRUE(ExceptionMaskToString(EXC_MASK_CRASH | EXC_MASK_GUARD,
+ kUseFullName).empty());
+ EXPECT_TRUE(ExceptionMaskToString(EXC_MASK_CRASH | EXC_MASK_GUARD,
+ kUseShortName).empty());
+ EXPECT_EQ("0x1400",
+ ExceptionMaskToString(EXC_MASK_CRASH | EXC_MASK_GUARD,
+ kUseFullName | kUnknownIsNumeric));
+ EXPECT_EQ("0x1400",
+ ExceptionMaskToString(EXC_MASK_CRASH | EXC_MASK_GUARD,
+ kUseShortName | kUnknownIsNumeric));
+ EXPECT_EQ("EXC_MASK_CRASH|EXC_MASK_GUARD",
+ ExceptionMaskToString(EXC_MASK_CRASH | EXC_MASK_GUARD,
+ kUseFullName | kUseOr));
+ EXPECT_EQ("CRASH|GUARD",
+ ExceptionMaskToString(EXC_MASK_CRASH | EXC_MASK_GUARD,
+ kUseShortName | kUseOr));
+}
+
+void TestStringToExceptionMask(const base::StringPiece& string,
+ StringToSymbolicConstantOptions options,
+ bool expect_result,
+ exception_mask_t expect_value) {
+ return TestStringToSomething<ConvertExceptionMaskTraits>(
+ string, options, expect_result, expect_value);
+}
+
+TEST(SymbolicConstantsMach, StringToExceptionMask) {
+ // Don’t use kNormalOptions, because kAllowOr needs to be tested.
+ const StringToSymbolicConstantOptions kOptions[] = {
+ 0,
+ kAllowFullName,
+ kAllowShortName,
+ kAllowFullName | kAllowShortName,
+ kAllowNumber,
+ kAllowFullName | kAllowNumber,
+ kAllowShortName | kAllowNumber,
+ kAllowFullName | kAllowShortName | kAllowNumber,
+ kAllowOr,
+ kAllowFullName | kAllowOr,
+ kAllowShortName | kAllowOr,
+ kAllowFullName | kAllowShortName | kAllowOr,
+ kAllowNumber | kAllowOr,
+ kAllowFullName | kAllowNumber | kAllowOr,
+ kAllowShortName | kAllowNumber | kAllowOr,
+ kAllowFullName | kAllowShortName | kAllowNumber | kAllowOr,
+ };
+
+ for (size_t option_index = 0;
+ option_index < arraysize(kOptions);
+ ++option_index) {
+ SCOPED_TRACE(base::StringPrintf("option_index %zu", option_index));
+ StringToSymbolicConstantOptions options = kOptions[option_index];
+ for (size_t index = 0; index < arraysize(kExceptionMaskTestData); ++index) {
+ SCOPED_TRACE(base::StringPrintf("index %zu", index));
+ exception_mask_t exception_mask =
+ kExceptionMaskTestData[index].exception_mask;
+ {
+ SCOPED_TRACE("full_name");
+ base::StringPiece full_name(kExceptionMaskTestData[index].full_name);
+ bool has_number = full_name.find("0x", 0) != base::StringPiece::npos;
+ bool has_or = full_name.find('|', 0) != base::StringPiece::npos;
+ bool allowed_characteristics =
+ (has_number ? (options & kAllowNumber) : true) &&
+ (has_or ? (options & kAllowOr) : true);
+ bool is_number = full_name.compare("0x1") == 0;
+ bool expect_valid =
+ ((options & kAllowFullName) && allowed_characteristics) ||
+ ((options & kAllowNumber) && is_number);
+ TestStringToExceptionMask(
+ full_name, options, expect_valid, exception_mask);
+ }
+ {
+ SCOPED_TRACE("short_name");
+ base::StringPiece short_name(kExceptionMaskTestData[index].short_name);
+ bool has_number = short_name.find("0x", 0) != base::StringPiece::npos;
+ bool has_or = short_name.find('|', 0) != base::StringPiece::npos;
+ bool allowed_characteristics =
+ (has_number ? (options & kAllowNumber) : true) &&
+ (has_or ? (options & kAllowOr) : true);
+ bool is_number = short_name.compare("0x1") == 0;
+ bool expect_valid =
+ ((options & kAllowShortName) && allowed_characteristics) ||
+ ((options & kAllowNumber) && is_number);
+ TestStringToExceptionMask(
+ short_name, options, expect_valid, exception_mask);
+ }
+ }
+
+ const char* const kNegativeTestData[] = {
+ "EXC_MASK_CRASH ",
+ " EXC_MASK_BAD_INSTRUCTION",
+ "EXC_MASK_EXC_MASK_BAD_ACCESS",
+ "EXC_MASK_SOFTWARES",
+ "EXC_MASK_JUNK",
+ "EXC_GUARD",
+ "EXC_ARITHMETIC|EXC_FAKE",
+ "ARITHMETIC|FAKE",
+ "FAKE|ARITHMETIC",
+ "EXC_FAKE|EXC_ARITHMETIC",
+ "random",
+ "",
+ };
+
+ for (size_t index = 0; index < arraysize(kNegativeTestData); ++index) {
+ SCOPED_TRACE(base::StringPrintf("index %zu", index));
+ TestStringToExceptionMask(kNegativeTestData[index], options, false, 0);
+ }
+
+ const struct {
+ const char* string;
+ size_t length;
+ } kNULTestData[] = {
+ NUL_TEST_DATA("\0EXC_MASK_ARITHMETIC"),
+ NUL_TEST_DATA("EXC_\0MASK_ARITHMETIC"),
+ NUL_TEST_DATA("EXC_MASK_\0ARITHMETIC"),
+ NUL_TEST_DATA("EXC_MASK_ARITH\0METIC"),
+ NUL_TEST_DATA("EXC_MASK_ARITHMETIC\0"),
+ NUL_TEST_DATA("\0ARITHMETIC"),
+ NUL_TEST_DATA("ARITH\0METIC"),
+ NUL_TEST_DATA("ARITHMETIC\0"),
+ NUL_TEST_DATA("\0003"),
+ NUL_TEST_DATA("3\0"),
+ NUL_TEST_DATA("1\0002"),
+ NUL_TEST_DATA("EXC_MASK_ARITHMETIC\0|EXC_MASK_EMULATION"),
+ NUL_TEST_DATA("EXC_MASK_ARITHMETIC|\0EXC_MASK_EMULATION"),
+ NUL_TEST_DATA("ARITHMETIC\0|EMULATION"),
+ NUL_TEST_DATA("ARITHMETIC|\0EMULATION"),
+ };
+
+ for (size_t index = 0; index < arraysize(kNULTestData); ++index) {
+ SCOPED_TRACE(base::StringPrintf("index %zu", index));
+ base::StringPiece string(kNULTestData[index].string,
+ kNULTestData[index].length);
+ TestStringToExceptionMask(string, options, false, 0);
+ }
+ }
+
+ const struct {
+ const char* string;
+ StringToSymbolicConstantOptions options;
+ exception_mask_t mask;
+ } kNonCanonicalTestData[] = {
+ {"EXC_MASK_ALL", kAllowFullName, ExcMaskAll()},
+ {"ALL", kAllowShortName, ExcMaskAll()},
+ {"EXC_MASK_ALL|EXC_MASK_CRASH",
+ kAllowFullName | kAllowOr,
+ ExcMaskAll() | EXC_MASK_CRASH},
+ {"ALL|CRASH",
+ kAllowShortName | kAllowOr,
+ ExcMaskAll() | EXC_MASK_CRASH},
+ {"EXC_MASK_BAD_INSTRUCTION|EXC_MASK_BAD_ACCESS",
+ kAllowFullName | kAllowOr,
+ EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION},
+ {"EMULATION|ARITHMETIC",
+ kAllowShortName | kAllowOr,
+ EXC_MASK_ARITHMETIC | EXC_MASK_EMULATION},
+ {"EXC_MASK_SOFTWARE|BREAKPOINT",
+ kAllowFullName | kAllowShortName | kAllowOr,
+ EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT},
+ {"SYSCALL|0x100",
+ kAllowShortName | kAllowNumber | kAllowOr,
+ EXC_MASK_SYSCALL | 0x100},
+ };
+
+ for (size_t index = 0; index < arraysize(kNonCanonicalTestData); ++index) {
+ SCOPED_TRACE(base::StringPrintf("index %zu", index));
+ TestStringToExceptionMask(kNonCanonicalTestData[index].string,
+ kNonCanonicalTestData[index].options,
+ true,
+ kNonCanonicalTestData[index].mask);
+ }
+
+ // Ensure that a NUL is not required at the end of the string.
+ {
+ SCOPED_TRACE("trailing_NUL_full");
+ TestStringToExceptionMask(base::StringPiece("EXC_MASK_BREAKPOINTED", 19),
+ kAllowFullName,
+ true,
+ EXC_MASK_BREAKPOINT);
+ }
+ {
+ SCOPED_TRACE("trailing_NUL_short");
+ TestStringToExceptionMask(base::StringPiece("BREAKPOINTED", 10),
+ kAllowShortName,
+ true,
+ EXC_MASK_BREAKPOINT);
+ }
+}
+
+const struct {
+ exception_behavior_t behavior;
+ const char* full_name;
+ const char* short_name;
+} kExceptionBehaviorTestData[] = {
+ {EXCEPTION_DEFAULT, "EXCEPTION_DEFAULT", "DEFAULT"},
+ {EXCEPTION_STATE, "EXCEPTION_STATE", "STATE"},
+ {EXCEPTION_STATE_IDENTITY, "EXCEPTION_STATE_IDENTITY", "STATE_IDENTITY"},
+ {static_cast<exception_behavior_t>(EXCEPTION_DEFAULT |
+ MACH_EXCEPTION_CODES),
+ "EXCEPTION_DEFAULT|MACH_EXCEPTION_CODES",
+ "DEFAULT|MACH"},
+ {static_cast<exception_behavior_t>(EXCEPTION_STATE |
+ MACH_EXCEPTION_CODES),
+ "EXCEPTION_STATE|MACH_EXCEPTION_CODES",
+ "STATE|MACH"},
+ {static_cast<exception_behavior_t>(EXCEPTION_STATE_IDENTITY |
+ MACH_EXCEPTION_CODES),
+ "EXCEPTION_STATE_IDENTITY|MACH_EXCEPTION_CODES",
+ "STATE_IDENTITY|MACH"},
+};
+
+struct ConvertExceptionBehaviorTraits {
+ typedef exception_behavior_t ValueType;
+ static std::string SomethingToString(
+ ValueType value,
+ SymbolicConstantToStringOptions options) {
+ return ExceptionBehaviorToString(value, options);
+ }
+ static bool StringToSomething(const base::StringPiece& string,
+ StringToSymbolicConstantOptions options,
+ ValueType* value) {
+ return StringToExceptionBehavior(string, options, value);
+ }
+ static const char kValueName[];
+};
+const char ConvertExceptionBehaviorTraits::kValueName[] = "behavior";
+
+void TestExceptionBehaviorToString(exception_behavior_t value,
+ const char* expect_full,
+ const char* expect_short) {
+ return TestSomethingToString<ConvertExceptionBehaviorTraits>(
+ value, expect_full, expect_short);
+}
+
+TEST(SymbolicConstantsMach, ExceptionBehaviorToString) {
+ for (size_t index = 0;
+ index < arraysize(kExceptionBehaviorTestData);
+ ++index) {
+ SCOPED_TRACE(base::StringPrintf("index %zu", index));
+ TestExceptionBehaviorToString(kExceptionBehaviorTestData[index].behavior,
+ kExceptionBehaviorTestData[index].full_name,
+ kExceptionBehaviorTestData[index].short_name);
+ }
+
+ for (exception_behavior_t behavior = 0; behavior < 8; ++behavior) {
+ SCOPED_TRACE(base::StringPrintf("behavior %d", behavior));
+ exception_behavior_t behavior_mach = behavior | MACH_EXCEPTION_CODES;
+ if (behavior > 0 && behavior <= EXCEPTION_STATE_IDENTITY) {
+ TestExceptionBehaviorToString(behavior, "", "");
+ TestExceptionBehaviorToString(behavior_mach, "", "");
+ } else {
+ TestExceptionBehaviorToString(behavior, NULL, NULL);
+ TestExceptionBehaviorToString(behavior_mach, NULL, NULL);
+ }
+ }
+}
+
+void TestStringToExceptionBehavior(const base::StringPiece& string,
+ StringToSymbolicConstantOptions options,
+ bool expect_result,
+ exception_behavior_t expect_value) {
+ return TestStringToSomething<ConvertExceptionBehaviorTraits>(
+ string, options, expect_result, expect_value);
+}
+
+TEST(SymbolicConstantsMach, StringToExceptionBehavior) {
+ for (size_t option_index = 0;
+ option_index < arraysize(kNormalOptions);
+ ++option_index) {
+ SCOPED_TRACE(base::StringPrintf("option_index %zu", option_index));
+ StringToSymbolicConstantOptions options = kNormalOptions[option_index];
+ for (size_t index = 0;
+ index < arraysize(kExceptionBehaviorTestData);
+ ++index) {
+ SCOPED_TRACE(base::StringPrintf("index %zu", index));
+ exception_behavior_t behavior =
+ kExceptionBehaviorTestData[index].behavior;
+ {
+ SCOPED_TRACE("full_name");
+ TestStringToExceptionBehavior(
+ kExceptionBehaviorTestData[index].full_name,
+ options,
+ options & kAllowFullName,
+ behavior);
+ }
+ {
+ SCOPED_TRACE("short_name");
+ TestStringToExceptionBehavior(
+ kExceptionBehaviorTestData[index].short_name,
+ options,
+ options & kAllowShortName,
+ behavior);
+ }
+ {
+ SCOPED_TRACE("number");
+ std::string number_string = base::StringPrintf("0x%x", behavior);
+ TestStringToExceptionBehavior(
+ number_string, options, options & kAllowNumber, behavior);
+ }
+ }
+
+ const char* const kNegativeTestData[] = {
+ "EXCEPTION_DEFAULT ",
+ " EXCEPTION_STATE",
+ "EXCEPTION_EXCEPTION_STATE_IDENTITY",
+ "EXCEPTION_DEFAULTS",
+ "EXCEPTION_JUNK",
+ "random",
+ "MACH_EXCEPTION_CODES",
+ "MACH",
+ "MACH_EXCEPTION_CODES|MACH_EXCEPTION_CODES",
+ "MACH_EXCEPTION_CODES|EXCEPTION_NONEXISTENT",
+ "MACH|junk",
+ "EXCEPTION_DEFAULT|EXCEPTION_STATE",
+ "1|2",
+ "",
+ };
+
+ for (size_t index = 0; index < arraysize(kNegativeTestData); ++index) {
+ SCOPED_TRACE(base::StringPrintf("index %zu", index));
+ TestStringToExceptionBehavior(
+ kNegativeTestData[index], options, false, 0);
+ }
+
+ const struct {
+ const char* string;
+ size_t length;
+ } kNULTestData[] = {
+ NUL_TEST_DATA("\0EXCEPTION_STATE_IDENTITY"),
+ NUL_TEST_DATA("EXCEPTION_\0STATE_IDENTITY"),
+ NUL_TEST_DATA("EXCEPTION_STATE\0_IDENTITY"),
+ NUL_TEST_DATA("EXCEPTION_STATE_IDENTITY\0"),
+ NUL_TEST_DATA("\0STATE_IDENTITY"),
+ NUL_TEST_DATA("STATE\0_IDENTITY"),
+ NUL_TEST_DATA("STATE_IDENTITY\0"),
+ NUL_TEST_DATA("\0003"),
+ NUL_TEST_DATA("3\0"),
+ NUL_TEST_DATA("0x8000000\0001"),
+ NUL_TEST_DATA("EXCEPTION_STATE_IDENTITY\0|MACH_EXCEPTION_CODES"),
+ NUL_TEST_DATA("EXCEPTION_STATE_IDENTITY|\0MACH_EXCEPTION_CODES"),
+ NUL_TEST_DATA("STATE_IDENTITY\0|MACH"),
+ NUL_TEST_DATA("STATE_IDENTITY|\0MACH"),
+ };
+
+ for (size_t index = 0; index < arraysize(kNULTestData); ++index) {
+ SCOPED_TRACE(base::StringPrintf("index %zu", index));
+ base::StringPiece string(kNULTestData[index].string,
+ kNULTestData[index].length);
+ TestStringToExceptionBehavior(string, options, false, 0);
+ }
+ }
+
+ const struct {
+ const char* string;
+ StringToSymbolicConstantOptions options;
+ exception_behavior_t behavior;
+ } kNonCanonicalTestData[] = {
+ {"MACH_EXCEPTION_CODES|EXCEPTION_STATE_IDENTITY",
+ kAllowFullName,
+ static_cast<exception_behavior_t>(EXCEPTION_STATE_IDENTITY |
+ MACH_EXCEPTION_CODES)},
+ {"MACH|STATE_IDENTITY",
+ kAllowShortName,
+ static_cast<exception_behavior_t>(EXCEPTION_STATE_IDENTITY |
+ MACH_EXCEPTION_CODES)},
+ {"MACH_EXCEPTION_CODES|STATE",
+ kAllowFullName | kAllowShortName,
+ static_cast<exception_behavior_t>(EXCEPTION_STATE |
+ MACH_EXCEPTION_CODES)},
+ {"MACH|EXCEPTION_STATE",
+ kAllowFullName | kAllowShortName,
+ static_cast<exception_behavior_t>(EXCEPTION_STATE |
+ MACH_EXCEPTION_CODES)},
+ {"3|MACH_EXCEPTION_CODES",
+ kAllowFullName | kAllowNumber,
+ static_cast<exception_behavior_t>(MACH_EXCEPTION_CODES | 3)},
+ {"MACH|0x2",
+ kAllowShortName | kAllowNumber,
+ static_cast<exception_behavior_t>(MACH_EXCEPTION_CODES | 0x2)},
+ };
+
+ for (size_t index = 0; index < arraysize(kNonCanonicalTestData); ++index) {
+ SCOPED_TRACE(base::StringPrintf("index %zu", index));
+ TestStringToExceptionBehavior(kNonCanonicalTestData[index].string,
+ kNonCanonicalTestData[index].options,
+ true,
+ kNonCanonicalTestData[index].behavior);
+ }
+
+ // Ensure that a NUL is not required at the end of the string.
+ {
+ SCOPED_TRACE("trailing_NUL_full");
+ TestStringToExceptionBehavior(base::StringPiece("EXCEPTION_DEFAULTS", 17),
+ kAllowFullName,
+ true,
+ EXCEPTION_DEFAULT);
+ }
+ {
+ SCOPED_TRACE("trailing_NUL_short");
+ TestStringToExceptionBehavior(base::StringPiece("DEFAULTS", 7),
+ kAllowShortName,
+ true,
+ EXCEPTION_DEFAULT);
+ }
+ {
+ SCOPED_TRACE("trailing_NUL_full_mach");
+ base::StringPiece string("EXCEPTION_DEFAULT|MACH_EXCEPTION_CODESS", 38);
+ TestStringToExceptionBehavior(string,
+ kAllowFullName | kAllowOr,
+ true,
+ EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES);
+ }
+ {
+ SCOPED_TRACE("trailing_NUL_short_mach");
+ TestStringToExceptionBehavior(base::StringPiece("DEFAULT|MACH_", 12),
+ kAllowShortName | kAllowOr,
+ true,
+ EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES);
+ }
+}
+
+const struct {
+ thread_state_flavor_t flavor;
+ const char* full_name;
+ const char* short_name;
+} kThreadStateFlavorTestData[] = {
+ {THREAD_STATE_NONE, "THREAD_STATE_NONE", "NONE"},
+ {THREAD_STATE_FLAVOR_LIST, "THREAD_STATE_FLAVOR_LIST", "FLAVOR_LIST"},
+ {THREAD_STATE_FLAVOR_LIST_NEW,
+ "THREAD_STATE_FLAVOR_LIST_NEW",
+ "FLAVOR_LIST_NEW"},
+ {THREAD_STATE_FLAVOR_LIST_10_9,
+ "THREAD_STATE_FLAVOR_LIST_10_9",
+ "FLAVOR_LIST_10_9"},
+#if defined(__i386__) || defined(__x86_64__)
+ {x86_THREAD_STATE32, "x86_THREAD_STATE32", "THREAD32"},
+ {x86_FLOAT_STATE32, "x86_FLOAT_STATE32", "FLOAT32"},
+ {x86_EXCEPTION_STATE32, "x86_EXCEPTION_STATE32", "EXCEPTION32"},
+ {x86_THREAD_STATE64, "x86_THREAD_STATE64", "THREAD64"},
+ {x86_FLOAT_STATE64, "x86_FLOAT_STATE64", "FLOAT64"},
+ {x86_EXCEPTION_STATE64, "x86_EXCEPTION_STATE64", "EXCEPTION64"},
+ {x86_THREAD_STATE, "x86_THREAD_STATE", "THREAD"},
+ {x86_FLOAT_STATE, "x86_FLOAT_STATE", "FLOAT"},
+ {x86_EXCEPTION_STATE, "x86_EXCEPTION_STATE", "EXCEPTION"},
+ {x86_DEBUG_STATE32, "x86_DEBUG_STATE32", "DEBUG32"},
+ {x86_DEBUG_STATE64, "x86_DEBUG_STATE64", "DEBUG64"},
+ {x86_DEBUG_STATE, "x86_DEBUG_STATE", "DEBUG"},
+ {14, "x86_SAVED_STATE32", "SAVED32"},
+ {15, "x86_SAVED_STATE64", "SAVED64"},
+ {x86_AVX_STATE32, "x86_AVX_STATE32", "AVX32"},
+ {x86_AVX_STATE64, "x86_AVX_STATE64", "AVX64"},
+ {x86_AVX_STATE, "x86_AVX_STATE", "AVX"},
+#elif defined(__ppc__) || defined(__ppc64__)
+ {PPC_THREAD_STATE, "PPC_THREAD_STATE", "THREAD"},
+ {PPC_FLOAT_STATE, "PPC_FLOAT_STATE", "FLOAT"},
+ {PPC_EXCEPTION_STATE, "PPC_EXCEPTION_STATE", "EXCEPTION"},
+ {PPC_VECTOR_STATE, "PPC_VECTOR_STATE", "VECTOR"},
+ {PPC_THREAD_STATE64, "PPC_THREAD_STATE64", "THREAD64"},
+ {PPC_EXCEPTION_STATE64, "PPC_EXCEPTION_STATE64", "EXCEPTION64"},
+#elif defined(__arm__) || defined(__arm64__)
+ {ARM_THREAD_STATE, "ARM_THREAD_STATE", "THREAD"},
+ {ARM_VFP_STATE, "ARM_VFP_STATE", "VFP"},
+ {ARM_EXCEPTION_STATE, "ARM_EXCEPTION_STATE", "EXCEPTION"},
+ {ARM_DEBUG_STATE, "ARM_DEBUG_STATE", "DEBUG"},
+ {ARM_THREAD_STATE64, "ARM_THREAD_STATE64", "THREAD64"},
+ {ARM_EXCEPTION_STATE64, "ARM_EXCEPTION_STATE64", "EXCEPTION64"},
+ {ARM_THREAD_STATE32, "ARM_THREAD_STATE32", "THREAD32"},
+ {ARM_DEBUG_STATE32, "ARM_DEBUG_STATE32", "DEBUG32"},
+ {ARM_DEBUG_STATE64, "ARM_DEBUG_STATE64", "DEBUG64"},
+ {ARM_NEON_STATE, "ARM_NEON_STATE", "NEON"},
+ {ARM_NEON_STATE64, "ARM_NEON_STATE64", "NEON64"},
+#endif
+};
+
+struct ConvertThreadStateFlavorTraits {
+ typedef thread_state_flavor_t ValueType;
+ static std::string SomethingToString(
+ ValueType value,
+ SymbolicConstantToStringOptions options) {
+ return ThreadStateFlavorToString(value, options);
+ }
+ static bool StringToSomething(const base::StringPiece& string,
+ StringToSymbolicConstantOptions options,
+ ValueType* value) {
+ return StringToThreadStateFlavor(string, options, value);
+ }
+ static const char kValueName[];
+};
+const char ConvertThreadStateFlavorTraits::kValueName[] = "flavor";
+
+void TestThreadStateFlavorToString(exception_type_t value,
+ const char* expect_full,
+ const char* expect_short) {
+ return TestSomethingToString<ConvertThreadStateFlavorTraits>(
+ value, expect_full, expect_short);
+}
+
+TEST(SymbolicConstantsMach, ThreadStateFlavorToString) {
+ for (size_t index = 0;
+ index < arraysize(kThreadStateFlavorTestData);
+ ++index) {
+ SCOPED_TRACE(base::StringPrintf("index %zu", index));
+ TestThreadStateFlavorToString(kThreadStateFlavorTestData[index].flavor,
+ kThreadStateFlavorTestData[index].full_name,
+ kThreadStateFlavorTestData[index].short_name);
+ }
+
+ for (thread_state_flavor_t flavor = 0; flavor < 136; ++flavor) {
+ SCOPED_TRACE(base::StringPrintf("flavor %d", flavor));
+
+ // Flavor numbers appear to be assigned somewhat haphazardly, especially on
+ // certain architectures. The conditional should match flavors that
+ // ThreadStateFlavorToString() knows how to convert.
+ if (
+#if defined(__i386__) || defined(__x86_64__)
+ flavor <= x86_AVX_STATE
+#elif defined(__ppc__) || defined(__ppc64__)
+ flavor <= THREAD_STATE_NONE
+#elif defined(__arm__) || defined(__arm64__)
+ (flavor <= ARM_EXCEPTION_STATE64 || flavor == ARM_THREAD_STATE32 ||
+ (flavor >= ARM_DEBUG_STATE32 && flavor <= ARM_NEON_STATE64))
+#endif
+ ||
+ flavor == THREAD_STATE_FLAVOR_LIST_NEW ||
+ flavor == THREAD_STATE_FLAVOR_LIST_10_9) {
+ TestThreadStateFlavorToString(flavor, "", "");
+ } else {
+ TestThreadStateFlavorToString(flavor, NULL, NULL);
+ }
+ }
+}
+
+void TestStringToThreadStateFlavor(const base::StringPiece& string,
+ StringToSymbolicConstantOptions options,
+ bool expect_result,
+ thread_state_flavor_t expect_value) {
+ return TestStringToSomething<ConvertThreadStateFlavorTraits>(
+ string, options, expect_result, expect_value);
+}
+
+TEST(SymbolicConstantsMach, StringToThreadStateFlavor) {
+ for (size_t option_index = 0;
+ option_index < arraysize(kNormalOptions);
+ ++option_index) {
+ SCOPED_TRACE(base::StringPrintf("option_index %zu", option_index));
+ StringToSymbolicConstantOptions options = kNormalOptions[option_index];
+ for (size_t index = 0;
+ index < arraysize(kThreadStateFlavorTestData);
+ ++index) {
+ SCOPED_TRACE(base::StringPrintf("index %zu", index));
+ thread_state_flavor_t flavor = kThreadStateFlavorTestData[index].flavor;
+ {
+ SCOPED_TRACE("full_name");
+ TestStringToThreadStateFlavor(
+ kThreadStateFlavorTestData[index].full_name,
+ options,
+ options & kAllowFullName,
+ flavor);
+ }
+ {
+ SCOPED_TRACE("short_name");
+ TestStringToThreadStateFlavor(
+ kThreadStateFlavorTestData[index].short_name,
+ options,
+ options & kAllowShortName,
+ flavor);
+ }
+ {
+ SCOPED_TRACE("number");
+ std::string number_string = base::StringPrintf("%d", flavor);
+ TestStringToThreadStateFlavor(
+ number_string, options, options & kAllowNumber, flavor);
+ }
+ }
+
+ const char* const kNegativeTestData[] = {
+ "THREAD_STATE_NONE ",
+ " THREAD_STATE_NONE",
+ "NONE ",
+ " NONE",
+ "THREAD_STATE_THREAD_STATE_NONE",
+ "THREAD_STATE_NONE_AT_ALL",
+ "NONE_AT_ALL",
+ "THREAD_STATE_JUNK",
+ "JUNK",
+ "random",
+ " THREAD64",
+ "THREAD64 ",
+ "THREAD642",
+ "",
+#if defined(__i386__) || defined(__x86_64__)
+ " x86_THREAD_STATE64",
+ "x86_THREAD_STATE64 ",
+ "x86_THREAD_STATE642",
+ "x86_JUNK",
+ "x86_JUNK_STATE32",
+ "PPC_THREAD_STATE",
+ "ARM_THREAD_STATE",
+#elif defined(__ppc__) || defined(__ppc64__)
+ " PPC_THREAD_STATE64",
+ "PPC_THREAD_STATE64 ",
+ "PPC_THREAD_STATE642",
+ "PPC_JUNK",
+ "PPC_JUNK_STATE32",
+ "x86_THREAD_STATE",
+ "ARM_THREAD_STATE",
+#elif defined(__arm__) || defined(__arm64__)
+ " ARM_THREAD_STATE64",
+ "ARM_THREAD_STATE64 ",
+ "ARM_THREAD_STATE642",
+ "ARM_JUNK",
+ "ARM_JUNK_STATE32",
+ "x86_THREAD_STATE",
+ "PPC_THREAD_STATE",
+#endif
+ };
+
+ for (size_t index = 0; index < arraysize(kNegativeTestData); ++index) {
+ SCOPED_TRACE(base::StringPrintf("index %zu", index));
+ TestStringToThreadStateFlavor(
+ kNegativeTestData[index], options, false, 0);
+ }
+
+ const struct {
+ const char* string;
+ size_t length;
+ } kNULTestData[] = {
+ NUL_TEST_DATA("\0THREAD_STATE_NONE"),
+ NUL_TEST_DATA("THREAD_\0STATE_NONE"),
+ NUL_TEST_DATA("THREAD_STATE_\0NONE"),
+ NUL_TEST_DATA("THREAD_STATE_NO\0NE"),
+ NUL_TEST_DATA("THREAD_STATE_NONE\0"),
+ NUL_TEST_DATA("\0NONE"),
+ NUL_TEST_DATA("NO\0NE"),
+ NUL_TEST_DATA("NONE\0"),
+ NUL_TEST_DATA("\0THREAD_STATE_FLAVOR_LIST_NEW"),
+ NUL_TEST_DATA("THREAD_STATE_\0FLAVOR_LIST_NEW"),
+ NUL_TEST_DATA("THREAD_STATE_FLAVOR_LIST\0_NEW"),
+ NUL_TEST_DATA("THREAD_STATE_FLAVOR_LIST_NEW\0"),
+ NUL_TEST_DATA("\0FLAVOR_LIST_NEW"),
+ NUL_TEST_DATA("FLAVOR_LIST\0_NEW"),
+ NUL_TEST_DATA("FLAVOR_LIST_NEW\0"),
+ NUL_TEST_DATA("\0THREAD"),
+ NUL_TEST_DATA("THR\0EAD"),
+ NUL_TEST_DATA("THREAD\0"),
+ NUL_TEST_DATA("\0THREAD64"),
+ NUL_TEST_DATA("THR\0EAD64"),
+ NUL_TEST_DATA("THREAD\064"),
+ NUL_TEST_DATA("THREAD64\0"),
+ NUL_TEST_DATA("\0002"),
+ NUL_TEST_DATA("2\0"),
+ NUL_TEST_DATA("1\0002"),
+#if defined(__i386__) || defined(__x86_64__)
+ NUL_TEST_DATA("\0x86_THREAD_STATE64"),
+ NUL_TEST_DATA("x86\0_THREAD_STATE64"),
+ NUL_TEST_DATA("x86_\0THREAD_STATE64"),
+ NUL_TEST_DATA("x86_THR\0EAD_STATE64"),
+ NUL_TEST_DATA("x86_THREAD\0_STATE64"),
+ NUL_TEST_DATA("x86_THREAD_\0STATE64"),
+ NUL_TEST_DATA("x86_THREAD_STA\0TE64"),
+ NUL_TEST_DATA("x86_THREAD_STATE\00064"),
+ NUL_TEST_DATA("x86_THREAD_STATE64\0"),
+#elif defined(__ppc__) || defined(__ppc64__)
+ NUL_TEST_DATA("\0PPC_THREAD_STATE64"),
+ NUL_TEST_DATA("PPC\0_THREAD_STATE64"),
+ NUL_TEST_DATA("PPC_\0THREAD_STATE64"),
+ NUL_TEST_DATA("PPC_THR\0EAD_STATE64"),
+ NUL_TEST_DATA("PPC_THREAD\0_STATE64"),
+ NUL_TEST_DATA("PPC_THREAD_\0STATE64"),
+ NUL_TEST_DATA("PPC_THREAD_STA\0TE64"),
+ NUL_TEST_DATA("PPC_THREAD_STATE\00064"),
+#elif defined(__arm__) || defined(__arm64__)
+ NUL_TEST_DATA("\0ARM_THREAD_STATE64"),
+ NUL_TEST_DATA("ARM\0_THREAD_STATE64"),
+ NUL_TEST_DATA("ARM_\0THREAD_STATE64"),
+ NUL_TEST_DATA("ARM_THR\0EAD_STATE64"),
+ NUL_TEST_DATA("ARM_THREAD\0_STATE64"),
+ NUL_TEST_DATA("ARM_THREAD_\0STATE64"),
+ NUL_TEST_DATA("ARM_THREAD_STA\0TE64"),
+ NUL_TEST_DATA("ARM_THREAD_STATE\00064"),
+#endif
+ };
+
+ for (size_t index = 0; index < arraysize(kNULTestData); ++index) {
+ SCOPED_TRACE(base::StringPrintf("index %zu", index));
+ base::StringPiece string(kNULTestData[index].string,
+ kNULTestData[index].length);
+ TestStringToThreadStateFlavor(string, options, false, 0);
+ }
+ }
+
+ // Ensure that a NUL is not required at the end of the string.
+ {
+ SCOPED_TRACE("trailing_NUL_full");
+ TestStringToThreadStateFlavor(base::StringPiece("THREAD_STATE_NONER", 17),
+ kAllowFullName,
+ true,
+ THREAD_STATE_NONE);
+ }
+ {
+ SCOPED_TRACE("trailing_NUL_short");
+ TestStringToThreadStateFlavor(base::StringPiece("NONER", 4),
+ kAllowShortName,
+ true,
+ THREAD_STATE_NONE);
+ }
+ {
+ SCOPED_TRACE("trailing_NUL_full_new");
+ base::StringPiece string("THREAD_STATE_FLAVOR_LIST_NEWS", 28);
+ TestStringToThreadStateFlavor(
+ string, kAllowFullName, true, THREAD_STATE_FLAVOR_LIST_NEW);
+ }
+ {
+ SCOPED_TRACE("trailing_NUL_short_new");
+ TestStringToThreadStateFlavor(base::StringPiece("FLAVOR_LIST_NEWS", 15),
+ kAllowShortName,
+ true,
+ THREAD_STATE_FLAVOR_LIST_NEW);
+ }
+}
+
+} // namespace
« no previous file with comments | « util/mach/symbolic_constants_mach.cc ('k') | util/posix/symbolic_constants_posix_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698