github.com/searKing/golang/go@v1.2.117/runtime/cgosymbolizer/symbolizer.cpp (about)

     1  // Copyright 2021 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  #include "symbolizer.h"
     5  
     6  #include <stdint.h>
     7  #include <string.h>
     8  #include <sys/types.h>
     9  
    10  #include <boost/stacktrace/frame.hpp>
    11  #include <boost/stacktrace/stacktrace.hpp>
    12  
    13  #include "traceback.h"
    14  
    15  static int append_pc_info_to_symbolizer_list(cgoSymbolizerArg* arg);
    16  static int append_entry_to_symbolizer_list(cgoSymbolizerArg* arg);
    17  
    18  // For the details of how this is called see runtime.SetCgoTraceback.
    19  void cgoSymbolizer(cgoSymbolizerArg* arg) {
    20    cgoSymbolizerMore* more = arg->data;
    21    if (more != NULL) {
    22      arg->file = more->file;
    23      arg->lineno = more->lineno;
    24      arg->func = more->func;
    25      // set non-zero if more info for this PC
    26      arg->more = more->more != NULL;
    27      arg->data = more->more;
    28  
    29      // If returning the last file/line, we can set the
    30      // entry point field.
    31      if (!arg->more) {  // no more info
    32        append_entry_to_symbolizer_list(arg);
    33      }
    34  
    35      return;
    36    }
    37    arg->file = NULL;
    38    arg->lineno = 0;
    39    arg->func = NULL;
    40    arg->more = 0;
    41    if (arg->pc == 0) {
    42      return;
    43    }
    44    append_pc_info_to_symbolizer_list(arg);
    45  
    46    // If returning only one file/line, we can set the entry point field.
    47    if (!arg->more) {
    48      append_entry_to_symbolizer_list(arg);
    49    }
    50  }
    51  
    52  void prepare_syminfo(const boost::stacktrace::detail::native_frame_ptr_t addr,
    53                       std::string& file, std::size_t& line, std::string& func) {
    54    auto frame = boost::stacktrace::frame(addr);
    55    file = frame.source_file();
    56    line = frame.source_line();
    57    func = frame.name();
    58  
    59    if (!func.empty()) {
    60      func = boost::core::demangle(func.c_str());
    61    } else {
    62      func = boost::stacktrace::detail::to_hex_array(addr).data();
    63    }
    64  
    65    if (file.empty() || file.find_first_of("?") == 0) {
    66      boost::stacktrace::detail::location_from_symbol loc(addr);
    67      if (!loc.empty()) {
    68        file = loc.name();
    69      }
    70    }
    71  }
    72  
    73  static int append_pc_info_to_symbolizer_list(cgoSymbolizerArg* arg) {
    74    std::string file;
    75    std::size_t line = 0;
    76    std::string func;
    77    prepare_syminfo(boost::stacktrace::frame::native_frame_ptr_t(arg->pc), file,
    78                    line, func);
    79    // init head with current stack
    80    if (arg->file == NULL) {
    81      arg->file = strdup(file.c_str());
    82      arg->lineno = line;
    83      arg->func = strdup(func.c_str());
    84      return 0;
    85    }
    86  
    87    cgoSymbolizerMore* more = (cgoSymbolizerMore*)malloc(sizeof(*more));
    88    if (more == NULL) {
    89      return 1;
    90    }
    91    // append current stack to the tail
    92    more->more = NULL;
    93    more->file = strdup(file.c_str());
    94    more->lineno = line;
    95    more->func = strdup(func.c_str());
    96    cgoSymbolizerMore** pp = NULL;
    97    for (pp = &arg->data; *pp != NULL; pp = &(*pp)->more) {
    98    }
    99    *pp = more;
   100    arg->more = 1;
   101    return 0;
   102  }
   103  
   104  static int append_entry_to_symbolizer_list(cgoSymbolizerArg* arg) {
   105    auto frame = boost::stacktrace::frame(
   106        boost::stacktrace::frame::native_frame_ptr_t(arg->pc));
   107    arg->entry = (uintptr_t)strdup(frame.name().c_str());
   108    return 0;
   109  }