type_error::type_error(const std::string& str) : message(str) { if(call_stack.empty() == false && call_stack.back()) { message += "\n" + call_stack.back()->debug_pinpoint_location(); } std::cerr << "ERROR: " << message << "\n" << get_call_stack(); std::cerr << output_formula_error_info(); }
const char* debuglib::callstack::CallStack::to_str() { get_call_stack(); std::vector<CS>::iterator itr; // offset used by memcpy int offset = 0; // max memory per symbol + remains char buffer[MAX_SYMBOL_LEN+200]; // allocating max memory that could be needed char* all = new char[(MAX_SYMBOL_LEN+200)*m_ces.size()]; // skip first function (to_str()) for(itr = m_ces.begin()+1; itr < m_ces.end(); ++itr ) { sprintf_s(buffer,MAX_SYMBOL_LEN+200, "%s() called\r\nBaseAddress: 0x%08llx\r\nReturnaddress: 0x%08llx\r\nIn File: %s (Line: %d)\r\n\r\n",itr->symbol_name, itr->base_address, itr->return_address, itr->file_name, itr->line_number); memcpy(all+offset,buffer,strlen(buffer)); offset+=strlen(buffer); } // terminate string with 0 byte all[offset] = '\0'; return all; }
type_error::type_error(const std::string& str) : game::error(str) { std::cerr << "ERROR: " << message << "\n" << get_call_stack(); }
type_error::type_error(const std::string& str) : message(str) { std::cerr << "ERROR: " << message << "\n" << get_call_stack(); output_formula_error_info(); }
void output_backtrace() { std::cerr << get_call_stack() << "\n"; }
//TODO: This may be specific to x86... Maybe abstract this in the future. CallStack::CallStack() { get_call_stack(); }