void ExitOnError(AMX *amx, int error) { if (error != AMX_ERR_NONE) { #if defined AMXDBG FILE *fp; AMX_DBG amxdbg; long line; const char *filename; #endif printf("Run time error %d: \"%s\" on address %ld\n", error, aux_StrError(error), (long)amx->cip); /* optionally use the debug library to find the line number (if debug info. * is available) */ #if defined AMXDBG /* load the debug info. */ if ((fp=fopen(g_filename,"rb")) != NULL && dbg_LoadInfo(&amxdbg,fp) == AMX_ERR_NONE) { dbg_LookupFile(&amxdbg, amx->cip, &filename); dbg_LookupLine(&amxdbg, amx->cip, &line); printf("File: %s, line: %ld\n", filename, line); dbg_FreeInfo(&amxdbg); fclose(fp); } /* if */ #endif exit(1); } /* if */ }
std::string DebugInfo::LookupFile(Address address) const { std::string result; const char *file; last_error_ = dbg_LookupFile(amxdbg_, address, &file); if (last_error_ == AMX_ERR_NONE) { result.assign(file); } return result; }
bool Debugger::GetTraceInfo(trace_info_t *pTraceInfo, long &line, const char *&function, const char *&file) { cell addr = pTraceInfo->cip; dbg_LookupFunction(m_pAmxDbg, addr, &function); dbg_LookupLine(m_pAmxDbg, addr, &line); dbg_LookupFile(m_pAmxDbg, addr, &file); return true; }
int AMXAPI dbg_GetFunctionAddress(AMX_DBG *amxdbg, const char *funcname, const char *filename, ucell *address) { /* Find a suitable "breakpoint address" close to the indicated line (and in * the specified file). The address is moved up to the first "breakable" line * in the function. You can use function dbg_LookupLine() to find out at which * precise line the breakpoint was set. * * The filename comparison is strict (case sensitive and path sensitive); the * "filename" parameter should point into the "filetbl" of the AMX_DBG * structure. The function name comparison is case sensitive too. */ int index, err; const char *tgtfile; ucell funcaddr; assert(amxdbg != NULL); assert(funcname != NULL); assert(filename != NULL); assert(address != NULL); *address = 0; index = 0; for ( ;; ) { /* find (next) matching function */ while (index < amxdbg->hdr->symbols && (amxdbg->symboltbl[index]->ident != iFUNCTN || strcmp(amxdbg->symboltbl[index]->name, funcname) != 0)) index++; if (index >= amxdbg->hdr->symbols) return AMX_ERR_NOTFOUND; /* verify that this line falls in the appropriate file */ err = dbg_LookupFile(amxdbg, amxdbg->symboltbl[index]->address, &tgtfile); if (err == AMX_ERR_NONE || strcmp(filename, tgtfile) == 0) break; index++; /* line is the wrong file, search further */ } /* for */ /* now find the first line in the function where we can "break" on */ assert(index < amxdbg->hdr->symbols); funcaddr = amxdbg->symboltbl[index]->address; for (index = 0; index < amxdbg->hdr->lines && amxdbg->linetbl[index].address < funcaddr; index++) /* nothing */; if (index >= amxdbg->hdr->lines) return AMX_ERR_NOTFOUND; *address = amxdbg->linetbl[index].address; return AMX_ERR_NONE; }