| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 | // Copyright 2018 The Abseil Authors.//// 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.// See "Retrieving Symbol Information by Address":// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680578(v=vs.85).aspx#include <windows.h>#include <DbgHelp.h>#pragma comment(lib, "DbgHelp")#include <algorithm>#include <cstring>#include "absl/base/internal/raw_logging.h"namespace absl {inline namespace lts_2018_12_18 {static HANDLE process = NULL;void InitializeSymbolizer(const char *argv0) {  if (process != nullptr) {    return;  }  process = GetCurrentProcess();  // Symbols are not loaded until a reference is made requiring the  // symbols be loaded. This is the fastest, most efficient way to use  // the symbol handler.  SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME);  if (!SymInitialize(process, nullptr, true)) {    // GetLastError() returns a Win32 DWORD, but we assign to    // unsigned long long to simplify the ABSL_RAW_LOG case below.  The uniform    // initialization guarantees this is not a narrowing conversion.    const unsigned long long error{GetLastError()};  // NOLINT(runtime/int)    ABSL_RAW_LOG(FATAL, "SymInitialize() failed: %llu", error);  }}bool Symbolize(const void *pc, char *out, int out_size) {  if (out_size <= 0) {    return false;  }  std::aligned_storage<sizeof(SYMBOL_INFO) + MAX_SYM_NAME,                       alignof(SYMBOL_INFO)>::type buf;  SYMBOL_INFO *symbol = reinterpret_cast<SYMBOL_INFO *>(&buf);  symbol->SizeOfStruct = sizeof(SYMBOL_INFO);  symbol->MaxNameLen = MAX_SYM_NAME;  if (!SymFromAddr(process, reinterpret_cast<DWORD64>(pc), nullptr, symbol)) {    return false;  }  strncpy(out, symbol->Name, out_size);  if (out[out_size - 1] != '\0') {    // strncpy() does not '\0' terminate when it truncates.    static constexpr char kEllipsis[] = "...";    int ellipsis_size =        std::min<int>(sizeof(kEllipsis) - 1, out_size - 1);    memcpy(out + out_size - ellipsis_size - 1, kEllipsis, ellipsis_size);    out[out_size - 1] = '\0';  }  return true;}}  // inline namespace lts_2018_12_18}  // namespace absl
 |