static BOOL DebugInterpreter(THREADID tid, CONTEXT *ctxt, const string &cmd, string *result, VOID *) { TINFO_MAP::iterator it = ThreadInfos.find(tid); if (it == ThreadInfos.end()) return FALSE; TINFO *tinfo = it->second; std::string line = TrimWhitespace(cmd); *result = ""; if (line == "help") { result->append("mappings -- Mappings.\n"); return TRUE; } else if(line == "mappings") { tinfo->_os.str(""); tinfo->_os << "{"; //open JSON for( IMG img= APP_ImgHead(); IMG_Valid(img); img = IMG_Next(img) ) { const string& name = LEVEL_PINCLIENT::IMG_Name(img); tinfo->_os <<"\""<< name << "\":{"; //open img ADDRINT address = LEVEL_PINCLIENT::IMG_LowAddress(img); tinfo->_os << "\"start\":" << address << ","; address = LEVEL_PINCLIENT::IMG_HighAddress(img); tinfo->_os << "\"end\":" << address << ","; tinfo->_os << "\"sections\":" << "{"; //open sections for( SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { const string& name = LEVEL_PINCLIENT::SEC_Name(sec); if(name != "") { tinfo->_os << "\"" << name <<"\":{"; //open section ADDRINT address = LEVEL_PINCLIENT::SEC_Address(sec); tinfo->_os << "\"start\":" << address << ","; USIZE size = LEVEL_PINCLIENT::SEC_Size(sec); if(SEC_Valid(SEC_Next(sec))) { tinfo->_os << "\"size\":" << size << "},"; //close section }else { tinfo->_os << "\"size\":" << size << "}}"; //close section and sections } } } if(IMG_Valid(IMG_Next(img))) { tinfo->_os << "},"; //close img }else { tinfo->_os << "}}"; //close img and json } } *result = tinfo->_os.str(); return TRUE; } return FALSE; /* Unknown command */ }
static VOID OnThreadEnd(THREADID tid, const CONTEXT *ctxt, INT32, VOID *) { TINFO_MAP::iterator it = ThreadInfos.find(tid); if (it != ThreadInfos.end()) { delete it->second; ThreadInfos.erase(it); } }
/* * This call-back implements the extended debugger commands. * * tid[in] Pin thread ID for debugger's "focus" thread. * ctxt[in,out] Register state for the debugger's "focus" thread. * cmd[in] Text of the extended command. * result[out] Text that the debugger prints when the command finishes. * * Returns: TRUE if we recognize this extended command. */ static BOOL DebugInterpreter(THREADID tid, CONTEXT *ctxt, const string &cmd, string *result, VOID *) { TINFO_MAP::iterator it = ThreadInfos.find(tid); if (it == ThreadInfos.end()) return FALSE; TINFO *tinfo = it->second; std::string line = TrimWhitespace(cmd); *result = ""; if (line == "help") { result->append("stacktrace on -- Enable tracing of stack usage.\n"); result->append("stacktrace off -- Disable tracing of stack usage.\n"); result->append("stats -- Show stack usage for current thread.\n"); result->append("stackbreak newmax -- Break when any thread stack reaches new maximum usage.\n"); result->append("stackbreak <number> -- Break when any thread stack usage exceeds <number> bytes.\n"); result->append("stackbreak off -- Disable stack breakpoints.\n"); return TRUE; } else if (line == "stats") { ADDRINT sp = PIN_GetContextReg(ctxt, REG_STACK_PTR); tinfo->_os.str(""); if (sp <= tinfo->_stackBase) tinfo->_os << "Current stack usage: " << std::dec << (tinfo->_stackBase - sp) << " bytes.\n"; else tinfo->_os << "Current stack usage: -" << std::dec << (sp - tinfo->_stackBase) << " bytes.\n"; tinfo->_os << "Maximum stack usage: " << tinfo->_max << " bytes.\n"; *result = tinfo->_os.str(); return TRUE; } else if (line == "stacktrace on") { if (!EnableInstrumentation) { PIN_RemoveInstrumentation(); EnableInstrumentation = true; *result = "Stack tracing enabled.\n"; } return TRUE; } else if (line == "stacktrace off") { if (EnableInstrumentation) { PIN_RemoveInstrumentation(); EnableInstrumentation = false; *result = "Stack tracing disabled.\n"; } return TRUE; } else if (line == "stackbreak newmax") { if (!EnableInstrumentation) { PIN_RemoveInstrumentation(); EnableInstrumentation = true; } BreakOnNewMax = true; BreakOnSize = 0; *result = "Will break when thread reaches new stack usage max.\n"; return TRUE; } else if (line == "stackbreak off") { BreakOnNewMax = false; BreakOnSize = 0; return TRUE; } else if (line.find("stackbreak ") == 0) { std::istringstream is(&line.c_str()[sizeof("stackbreak ")-1]); size_t size; is >> size; if (!is) { *result = "Please specify a numeric size (in bytes)\n"; return TRUE; } if (!EnableInstrumentation) { PIN_RemoveInstrumentation(); EnableInstrumentation = true; } BreakOnNewMax = false; BreakOnSize = size; tinfo->_os.str(""); tinfo->_os << "Will break when thread uses more than " << size << " bytes of stack.\n"; *result = tinfo->_os.str(); return TRUE; }
static VOID OnThreadStart(THREADID tid, CONTEXT *ctxt, INT32, VOID *) { TINFO *tinfo = new TINFO(PIN_GetContextReg(ctxt, REG_STACK_PTR)); ThreadInfos.insert(std::make_pair(tid, tinfo)); PIN_SetContextReg(ctxt, RegTinfo, reinterpret_cast<ADDRINT>(tinfo)); }