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 */ }
Debugger::~Debugger() { Clear(); dbg_FreeInfo(m_pAmxDbg); delete m_pAmxDbg; }
int AMXAPI dbg_LoadInfo(AMX_DBG *amxdbg, FILE *fp) { AMX_HEADER amxhdr; AMX_DBG_HDR dbghdr; size_t size; unsigned char *ptr; int index, dim; AMX_DBG_LINE *line; AMX_DBG_SYMDIM *symdim; assert(fp != NULL); assert(amxdbg != NULL); memset(&amxhdr, 0, sizeof amxhdr); fseek(fp, 0L, SEEK_SET); if (fread(&amxhdr, sizeof amxhdr, 1, fp) == 0) return AMX_ERR_FORMAT; #if BYTE_ORDER==BIG_ENDIAN amx_Align32((uint32_t*)&amxhdr.size); amx_Align16(&amxhdr.magic); amx_Align16(&dbghdr.flags); #endif if (amxhdr.magic != AMX_MAGIC) return AMX_ERR_FORMAT; if ((amxhdr.flags & AMX_FLAG_DEBUG) == 0) return AMX_ERR_DEBUG; fseek(fp, amxhdr.size, SEEK_SET); memset(&dbghdr, 0, sizeof(AMX_DBG_HDR)); if (fread(&dbghdr, sizeof(AMX_DBG_HDR), 1, fp) == 0) return AMX_ERR_FORMAT; #if BYTE_ORDER==BIG_ENDIAN amx_Align32((uint32_t*)&dbghdr.size); amx_Align16(&dbghdr.magic); amx_Align16(&dbghdr.flags); amx_Align16(&dbghdr.files); amx_Align16(&dbghdr.lines); amx_Align16(&dbghdr.symbols); amx_Align16(&dbghdr.tags); amx_Align16(&dbghdr.automatons); amx_Align16(&dbghdr.states); #endif if (dbghdr.magic != AMX_DBG_MAGIC) return AMX_ERR_FORMAT; /* allocate all memory */ memset(amxdbg, 0, sizeof(AMX_DBG)); amxdbg->hdr = malloc((size_t)dbghdr.size); if (dbghdr.files > 0) amxdbg->filetbl = malloc(dbghdr.files * sizeof(AMX_DBG_FILE *)); if (dbghdr.symbols > 0) amxdbg->symboltbl = malloc(dbghdr.symbols * sizeof(AMX_DBG_SYMBOL *)); if (dbghdr.tags > 0) amxdbg->tagtbl = malloc(dbghdr.tags * sizeof(AMX_DBG_TAG *)); if (dbghdr.automatons > 0) amxdbg->automatontbl = malloc(dbghdr.automatons * sizeof(AMX_DBG_MACHINE *)); if (dbghdr.states > 0) amxdbg->statetbl = malloc(dbghdr.states * sizeof(AMX_DBG_STATE *)); if (amxdbg->hdr == NULL || (dbghdr.files > 0 && amxdbg->filetbl == NULL) || (dbghdr.symbols > 0 && amxdbg->symboltbl == NULL) || (dbghdr.tags > 0 && amxdbg->tagtbl == NULL) || (dbghdr.states > 0 && amxdbg->statetbl == NULL) || (dbghdr.automatons > 0 && amxdbg->automatontbl == NULL)) { dbg_FreeInfo(amxdbg); return AMX_ERR_MEMORY; } /* if */ /* load the entire symbolic information block into memory */ memcpy(amxdbg->hdr, &dbghdr, sizeof dbghdr); size=(size_t)(dbghdr.size - sizeof dbghdr); if (fread(amxdbg->hdr + 1, 1, size, fp) < size) { dbg_FreeInfo(amxdbg); return AMX_ERR_FORMAT; } /* if */ /* run through the file, fix alignment issues and set up table pointers */ ptr = (unsigned char *)(amxdbg->hdr + 1); /* file table */ for (index = 0; index < dbghdr.files; index++) { assert(amxdbg->filetbl != NULL); amxdbg->filetbl[index] = (AMX_DBG_FILE *)ptr; #if BYTE_ORDER==BIG_ENDIAN amx_AlignCell(&amxdbg->filetbl[index]->address); #endif for (ptr = ptr + sizeof(AMX_DBG_FILE); *ptr != '\0'; ptr++) /* nothing */; ptr++; /* skip '\0' too */ } /* for */ /* line table */ amxdbg->linetbl = (AMX_DBG_LINE*)ptr; #if BYTE_ORDER==BIG_ENDIAN for (index = 0; index < dbghdr.lines; index++) { amx_AlignCell(&amxdbg->linetbl[index].address); amx_Align32((uint32_t*)&amxdbg->linetbl[index].line); } /* for */ #endif ptr += (uint16_t)dbghdr.lines * sizeof(AMX_DBG_LINE); /* detect dbghdr.lines overflow */ while ((line = (AMX_DBG_LINE *)ptr) && (cell)line->address > (cell)(line - 1)->address) { #if BYTE_ORDER==BIG_ENDIAN for (index = 0; index <= (uint32_t)(1u << 16) - 1; index++) { amx_AlignCell(&linetbl[index].address); amx_Align32((uint32_t*)&linetbl[index].line); line++; } /* for */ #endif ptr += (uint32_t)(1u << 16) * sizeof(AMX_DBG_LINE); } /* while */ /* symbol table (plus index tags) */ for (index = 0; index < dbghdr.symbols; index++) { assert(amxdbg->symboltbl != NULL); amxdbg->symboltbl[index] = (AMX_DBG_SYMBOL *)ptr; #if BYTE_ORDER==BIG_ENDIAN amx_AlignCell(&amxdbg->symboltbl[index]->address); amx_Align16((uint16_t*)&amxdbg->symboltbl[index]->tag); amx_AlignCell(&amxdbg->symboltbl[index]->codestart); amx_AlignCell(&amxdbg->symboltbl[index]->codeend); amx_Align16((uint16_t*)&amxdbg->symboltbl[index]->dim); #endif for (ptr = ptr + sizeof(AMX_DBG_SYMBOL); *ptr != '\0'; ptr++) /* nothing */; ptr++; /* skip '\0' too */ for (dim = 0; dim < amxdbg->symboltbl[index]->dim; dim++) { symdim = (AMX_DBG_SYMDIM *)ptr; amx_Align16((uint16_t*)&symdim->tag); amx_AlignCell(&symdim->size); ptr += sizeof(AMX_DBG_SYMDIM); } /* for */ } /* for */ /* tag name table */ for (index = 0; index < dbghdr.tags; index++) { assert(amxdbg->tagtbl != NULL); amxdbg->tagtbl[index] = (AMX_DBG_TAG *)ptr; #if BYTE_ORDER==BIG_ENDIAN amx_Align16(&amxdbg->tagtbl[index]->tag); #endif for (ptr = ptr + sizeof(AMX_DBG_TAG) - 1; *ptr != '\0'; ptr++) /* nothing */; ptr++; /* skip '\0' too */ } /* for */ /* automaton name table */ for (index = 0; index < dbghdr.automatons; index++) { assert(amxdbg->automatontbl != NULL); amxdbg->automatontbl[index] = (AMX_DBG_MACHINE *)ptr; #if BYTE_ORDER==BIG_ENDIAN amx_Align16(&amxdbg->automatontbl[index]->automaton); amx_AlignCell(&amxdbg->automatontbl[index]->address); #endif for (ptr = ptr + sizeof(AMX_DBG_MACHINE) - 1; *ptr != '\0'; ptr++) /* nothing */; ptr++; /* skip '\0' too */ } /* for */ /* state name table */ for (index = 0; index < dbghdr.states; index++) { assert(amxdbg->statetbl != NULL); amxdbg->statetbl[index] = (AMX_DBG_STATE *)ptr; #if BYTE_ORDER==BIG_ENDIAN amx_Align16(&amxdbg->statetbl[index]->state); amx_Align16(&amxdbg->automatontbl[index]->automaton); #endif for (ptr = ptr + sizeof(AMX_DBG_STATE) - 1; *ptr != '\0'; ptr++) /* nothing */; ptr++; /* skip '\0' too */ } /* for */ return AMX_ERR_NONE; }
void DebugInfo::Unload() { if (amxdbg_ != 0) { last_error_ = dbg_FreeInfo(amxdbg_); delete amxdbg_; } }