00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "absl/debugging/internal/demangle.h"
00016
00017 #include <cstdlib>
00018 #include <string>
00019
00020 #include "gtest/gtest.h"
00021 #include "absl/base/internal/raw_logging.h"
00022 #include "absl/debugging/internal/stack_consumption.h"
00023 #include "absl/memory/memory.h"
00024
00025 namespace absl {
00026 namespace debugging_internal {
00027 namespace {
00028
00029
00030 static const char *DemangleIt(const char * const mangled) {
00031 static char demangled[4096];
00032 if (Demangle(mangled, demangled, sizeof(demangled))) {
00033 return demangled;
00034 } else {
00035 return mangled;
00036 }
00037 }
00038
00039
00040 TEST(Demangle, CornerCases) {
00041 char tmp[10];
00042 EXPECT_TRUE(Demangle("_Z6foobarv", tmp, sizeof(tmp)));
00043
00044 EXPECT_STREQ("foobar()", tmp);
00045 EXPECT_TRUE(Demangle("_Z6foobarv", tmp, 9));
00046 EXPECT_STREQ("foobar()", tmp);
00047 EXPECT_FALSE(Demangle("_Z6foobarv", tmp, 8));
00048 EXPECT_FALSE(Demangle("_Z6foobarv", tmp, 1));
00049 EXPECT_FALSE(Demangle("_Z6foobarv", tmp, 0));
00050 EXPECT_FALSE(Demangle("_Z6foobarv", nullptr, 0));
00051 EXPECT_FALSE(Demangle("_Z1000000", tmp, 9));
00052 }
00053
00054
00055
00056
00057
00058
00059 TEST(Demangle, Clones) {
00060 char tmp[20];
00061 EXPECT_TRUE(Demangle("_ZL3Foov", tmp, sizeof(tmp)));
00062 EXPECT_STREQ("Foo()", tmp);
00063 EXPECT_TRUE(Demangle("_ZL3Foov.clone.3", tmp, sizeof(tmp)));
00064 EXPECT_STREQ("Foo()", tmp);
00065 EXPECT_TRUE(Demangle("_ZL3Foov.constprop.80", tmp, sizeof(tmp)));
00066 EXPECT_STREQ("Foo()", tmp);
00067 EXPECT_TRUE(Demangle("_ZL3Foov.isra.18", tmp, sizeof(tmp)));
00068 EXPECT_STREQ("Foo()", tmp);
00069 EXPECT_TRUE(Demangle("_ZL3Foov.isra.2.constprop.18", tmp, sizeof(tmp)));
00070 EXPECT_STREQ("Foo()", tmp);
00071
00072 EXPECT_FALSE(Demangle("_ZL3Foov.clo", tmp, sizeof(tmp)));
00073
00074 EXPECT_FALSE(Demangle("_ZL3Foov.clone.", tmp, sizeof(tmp)));
00075
00076 EXPECT_FALSE(Demangle("_ZL3Foov.clone.foo", tmp, sizeof(tmp)));
00077
00078 EXPECT_FALSE(Demangle("_ZL3Foov.isra.2.constprop.", tmp, sizeof(tmp)));
00079 }
00080
00081
00082
00083
00084 #if defined(ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION) && \
00085 !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) && \
00086 !defined(THREAD_SANITIZER)
00087
00088 static const char *g_mangled;
00089 static char g_demangle_buffer[4096];
00090 static char *g_demangle_result;
00091
00092 static void DemangleSignalHandler(int signo) {
00093 if (Demangle(g_mangled, g_demangle_buffer, sizeof(g_demangle_buffer))) {
00094 g_demangle_result = g_demangle_buffer;
00095 } else {
00096 g_demangle_result = nullptr;
00097 }
00098 }
00099
00100
00101 static const char *DemangleStackConsumption(const char *mangled,
00102 int *stack_consumed) {
00103 g_mangled = mangled;
00104 *stack_consumed = GetSignalHandlerStackConsumption(DemangleSignalHandler);
00105 ABSL_RAW_LOG(INFO, "Stack consumption of Demangle: %d", *stack_consumed);
00106 return g_demangle_result;
00107 }
00108
00109
00110
00111
00112
00113 const int kStackConsumptionUpperLimit = 8192;
00114
00115
00116 static std::string NestedMangledName(int depth) {
00117 std::string mangled_name = "_Z1a";
00118 if (depth > 0) {
00119 mangled_name += "IXL";
00120 mangled_name += NestedMangledName(depth - 1);
00121 mangled_name += "EEE";
00122 }
00123 return mangled_name;
00124 }
00125
00126 TEST(Demangle, DemangleStackConsumption) {
00127
00128
00129
00130
00131
00132 int stack_consumed = 0;
00133
00134 const char *demangled =
00135 DemangleStackConsumption("_Z6foobarv", &stack_consumed);
00136 EXPECT_STREQ("foobar()", demangled);
00137 EXPECT_GT(stack_consumed, 0);
00138 EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
00139
00140 const std::string nested_mangled_name0 = NestedMangledName(0);
00141 demangled = DemangleStackConsumption(nested_mangled_name0.c_str(),
00142 &stack_consumed);
00143 EXPECT_STREQ("a", demangled);
00144 EXPECT_GT(stack_consumed, 0);
00145 EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
00146
00147 const std::string nested_mangled_name1 = NestedMangledName(1);
00148 demangled = DemangleStackConsumption(nested_mangled_name1.c_str(),
00149 &stack_consumed);
00150 EXPECT_STREQ("a<>", demangled);
00151 EXPECT_GT(stack_consumed, 0);
00152 EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
00153
00154 const std::string nested_mangled_name2 = NestedMangledName(2);
00155 demangled = DemangleStackConsumption(nested_mangled_name2.c_str(),
00156 &stack_consumed);
00157 EXPECT_STREQ("a<>", demangled);
00158 EXPECT_GT(stack_consumed, 0);
00159 EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
00160
00161 const std::string nested_mangled_name3 = NestedMangledName(3);
00162 demangled = DemangleStackConsumption(nested_mangled_name3.c_str(),
00163 &stack_consumed);
00164 EXPECT_STREQ("a<>", demangled);
00165 EXPECT_GT(stack_consumed, 0);
00166 EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
00167 }
00168
00169 #endif // Stack consumption tests
00170
00171 static void TestOnInput(const char* input) {
00172 static const int kOutSize = 1048576;
00173 auto out = absl::make_unique<char[]>(kOutSize);
00174 Demangle(input, out.get(), kOutSize);
00175 }
00176
00177 TEST(DemangleRegression, NegativeLength) {
00178 TestOnInput("_ZZn4");
00179 }
00180
00181 TEST(DemangleRegression, DeeplyNestedArrayType) {
00182 const int depth = 100000;
00183 std::string data = "_ZStI";
00184 data.reserve(data.size() + 3 * depth + 1);
00185 for (int i = 0; i < depth; i++) {
00186 data += "A1_";
00187 }
00188 TestOnInput(data.c_str());
00189 }
00190
00191 }
00192 }
00193 }