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 }