Index: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc =================================================================== --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc @@ -356,11 +356,19 @@ CHECK(module_name); const char *is_data_str = is_data ? "DATA " : ""; if (arch == kModuleArchUnknown) { - internal_snprintf(buffer_, kBufferSize, "%s\"%s\" 0x%zx\n", is_data_str, - module_name, module_offset); + if (internal_snprintf(buffer_, kBufferSize, "%s\"%s\" 0x%zx\n", is_data_str, + module_name, + module_offset) >= static_cast(kBufferSize)) { + Report("WARNING: Command buffer too small"); + return nullptr; + } } else { - internal_snprintf(buffer_, kBufferSize, "%s\"%s:%s\" 0x%zx\n", is_data_str, - module_name, ModuleArchToString(arch), module_offset); + if (internal_snprintf(buffer_, kBufferSize, "%s\"%s:%s\" 0x%zx\n", + is_data_str, module_name, ModuleArchToString(arch), + module_offset) >= static_cast(kBufferSize)) { + Report("WARNING: Command buffer too small"); + return nullptr; + } } return symbolizer_process_->SendCommand(buffer_); } @@ -426,6 +434,11 @@ read_len += just_read; if (ReachedEndOfOutput(buffer, read_len)) break; + if (read_len + 1 == max_length) { + Report("WARNING: Symbolizer buffer too small"); + read_len = 0; + break; + } } buffer[read_len] = '\0'; return true; Index: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc =================================================================== --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc @@ -424,7 +424,6 @@ InternalSymbolizer() { } static const int kBufferSize = 16 * 1024; - static const int kMaxDemangledNameSize = 1024; char buffer_[kBufferSize]; }; #else // SANITIZER_SUPPORTS_WEAK_HOOKS Index: compiler-rt/trunk/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cc =================================================================== --- compiler-rt/trunk/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cc +++ compiler-rt/trunk/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cc @@ -41,8 +41,8 @@ getDefaultSymbolizer()->symbolizeInlinedCode(ModuleName, ModuleOffset); Printer << (ResOrErr ? ResOrErr.get() : llvm::DIInliningInfo()); } - __sanitizer::internal_snprintf(Buffer, MaxLength, "%s", Result.c_str()); - return true; + return __sanitizer::internal_snprintf(Buffer, MaxLength, "%s", + Result.c_str()) < MaxLength; } bool __sanitizer_symbolize_data(const char *ModuleName, uint64_t ModuleOffset, @@ -55,8 +55,8 @@ getDefaultSymbolizer()->symbolizeData(ModuleName, ModuleOffset); Printer << (ResOrErr ? ResOrErr.get() : llvm::DIGlobal()); } - __sanitizer::internal_snprintf(Buffer, MaxLength, "%s", Result.c_str()); - return true; + return __sanitizer::internal_snprintf(Buffer, MaxLength, "%s", + Result.c_str()) < MaxLength; } void __sanitizer_symbolize_flush() { getDefaultSymbolizer()->flush(); } @@ -65,8 +65,10 @@ int MaxLength) { std::string Result = llvm::symbolize::LLVMSymbolizer::DemangleName(Name, nullptr); - __sanitizer::internal_snprintf(Buffer, MaxLength, "%s", Result.c_str()); - return static_cast(Result.size() + 1); + return __sanitizer::internal_snprintf(Buffer, MaxLength, "%s", + Result.c_str()) < MaxLength + ? static_cast(Result.size() + 1) + : 0; } } // extern "C" Index: compiler-rt/trunk/test/sanitizer_common/TestCases/symbolize_stack.cc =================================================================== --- compiler-rt/trunk/test/sanitizer_common/TestCases/symbolize_stack.cc +++ compiler-rt/trunk/test/sanitizer_common/TestCases/symbolize_stack.cc @@ -0,0 +1,28 @@ +// RUN: %clangxx -O0 %s -o %t && %run %t 2>&1 | FileCheck %s + +// Test that symbolizer does not crash on frame with large function name. + +#include +#include + +template struct A { + template void RecursiveTemplateFunction(const T &t); +}; + +template +template +__attribute__((noinline)) void A::RecursiveTemplateFunction(const T &) { + std::vector t; + return A().RecursiveTemplateFunction(t); +} + +template <> +template +__attribute__((noinline)) void A<0>::RecursiveTemplateFunction(const T &) { + __sanitizer_print_stack_trace(); +} + +int main() { + // CHECK: {{vector<.*vector<.*vector<.*vector<.*vector<}} + A<10>().RecursiveTemplateFunction(0); +}