Fixed horrendous crash in the JIT from packing change in the debug table (bug 3334, r=me).

I accidentally changed the debug table packing in a commit a while ago.  This explains the nonsense debug output and crashes people have been getting on the 1.1 branch.  Fortunately this is (mostly) detectable via the "debug.natives" table and the JIT will unpack symbols based on that information.
This commit is contained in:
David Anderson 2008-10-27 02:02:14 -05:00
parent e48bba5b4d
commit 8d78c74554
6 changed files with 155 additions and 42 deletions

View File

@ -57,7 +57,7 @@
#endif #endif
#define SPFILE_MAGIC 0x53504646 /**< Source Pawn File Format (SPFF) */ #define SPFILE_MAGIC 0x53504646 /**< Source Pawn File Format (SPFF) */
#define SPFILE_VERSION 0x0101 /**< Uncompressed bytecode */ #define SPFILE_VERSION 0x0102 /**< File format version */
//:TODO: better compiler/nix support //:TODO: better compiler/nix support
#if defined __linux__ #if defined __linux__
@ -266,4 +266,40 @@ typedef struct fp_fdbg_ntvarg_s
#pragma pack(pop) /* reset previous packing */ #pragma pack(pop) /* reset previous packing */
#endif #endif
/**
* Okay, my mistake here. I apologize. I changed the packing by accident and there is no
* version bump aside from the presence of the native debug table. Cat's out of the bag
* for SourceMod and we have no choice but to shim compat for the old version. For people
* parsing plugins on their own, use the presence of the native debug table to decide this.
* If there are no natives (really, there is a very very low chance of this), heuristics
* might be necessary. I've bumped the version to 0x0102 but there may have been plugins
* in the 0x0101 window with no natives.
*/
/**
* @brief Unpacked file-encoded debug symbol array dimension info.
*/
typedef struct sp_u_fdbg_arraydim_s
{
int16_t tagid; /**< Tag id */
uint32_t size; /**< Size of dimension */
} sp_u_fdbg_arraydim_t;
/**
* @brief Unpacked file-encoded debug symbol information.
*/
typedef struct sp_u_fdbg_symbol_s
{
int32_t addr; /**< Address rel to DAT or stack frame */
int16_t tagid; /**< Tag id */
uint32_t codestart; /**< Start scope validity in code */
uint32_t codeend; /**< End scope validity in code */
uint8_t ident; /**< Variable type */
uint8_t vclass; /**< Scope class (local vs global) */
uint16_t dimcount; /**< Dimension count (for arrays) */
uint32_t name; /**< Offset into debug nametable */
} sp_u_fdbg_symbol_t;
#endif //_INCLUDE_SPFILE_HEADERS_H #endif //_INCLUDE_SPFILE_HEADERS_H

View File

@ -69,6 +69,11 @@ int BaseRuntime::CreateFromMemory(sp_file_hdr_t *hdr, uint8_t *base)
plugin->base_size = hdr->imagesize; plugin->base_size = hdr->imagesize;
set_err = SP_ERROR_NONE; set_err = SP_ERROR_NONE;
if (hdr->version == 0x0101)
{
plugin->debug.unpacked = true;
}
/* We have to read the name section first */ /* We have to read the name section first */
for (sectnum = 0; sectnum < hdr->sections; sectnum++) for (sectnum = 0; sectnum < hdr->sections; sectnum++)
{ {
@ -195,6 +200,10 @@ int BaseRuntime::CreateFromMemory(sp_file_hdr_t *hdr, uint8_t *base)
{ {
plugin->debug.stringbase = (const char *)(base + secptr->dataoffs); plugin->debug.stringbase = (const char *)(base + secptr->dataoffs);
} }
else if (strcmp(nameptr, ".dbg.natives") == 0)
{
plugin->debug.unpacked = false;
}
secptr++; secptr++;
sectnum++; sectnum++;

View File

@ -88,7 +88,6 @@ IPluginRuntime *SourcePawnEngine2::LoadPlugin(ICompilation *co, const char *file
} }
} }
pRuntime = new BaseRuntime(); pRuntime = new BaseRuntime();
if ((error = pRuntime->CreateFromMemory(&hdr, base)) != SP_ERROR_NONE) if ((error = pRuntime->CreateFromMemory(&hdr, base)) != SP_ERROR_NONE)
{ {

View File

@ -19,6 +19,7 @@ typedef struct sp_plugin_debug_s
sp_fdbg_line_t *lines; /**< lines table */ sp_fdbg_line_t *lines; /**< lines table */
uint32_t syms_num; /**< number of symbols */ uint32_t syms_num; /**< number of symbols */
sp_fdbg_symbol_t *symbols; /**< symbol table */ sp_fdbg_symbol_t *symbols; /**< symbol table */
bool unpacked; /**< Whether debug structures are unpacked */
} sp_plugin_debug_t; } sp_plugin_debug_t;
class BaseContext; class BaseContext;

View File

@ -742,37 +742,72 @@ int DebugInfo::LookupFile(ucell_t addr, const char **filename)
int DebugInfo::LookupFunction(ucell_t addr, const char **name) int DebugInfo::LookupFunction(ucell_t addr, const char **name)
{ {
uint32_t max, iter; if (!m_pPlugin->debug.unpacked)
sp_fdbg_symbol_t *sym;
sp_fdbg_arraydim_t *arr;
uint8_t *cursor = (uint8_t *)(m_pPlugin->debug.symbols);
max = m_pPlugin->debug.syms_num;
for (iter = 0; iter < max; iter++)
{ {
sym = (sp_fdbg_symbol_t *)cursor; uint32_t max, iter;
sp_fdbg_symbol_t *sym;
sp_fdbg_arraydim_t *arr;
uint8_t *cursor = (uint8_t *)(m_pPlugin->debug.symbols);
if (sym->ident == SP_SYM_FUNCTION max = m_pPlugin->debug.syms_num;
&& sym->codestart <= addr for (iter = 0; iter < max; iter++)
&& sym->codeend > addr)
{ {
*name = m_pPlugin->debug.stringbase + sym->name; sym = (sp_fdbg_symbol_t *)cursor;
return SP_ERROR_NONE;
} if (sym->ident == SP_SYM_FUNCTION
&& sym->codestart <= addr
&& sym->codeend > addr)
{
*name = m_pPlugin->debug.stringbase + sym->name;
return SP_ERROR_NONE;
}
if (sym->dimcount > 0)
{
cursor += sizeof(sp_fdbg_symbol_t);
arr = (sp_fdbg_arraydim_t *)cursor;
cursor += sizeof(sp_fdbg_arraydim_t) * sym->dimcount;
continue;
}
if (sym->dimcount > 0)
{
cursor += sizeof(sp_fdbg_symbol_t); cursor += sizeof(sp_fdbg_symbol_t);
arr = (sp_fdbg_arraydim_t *)cursor;
cursor += sizeof(sp_fdbg_arraydim_t) * sym->dimcount;
continue;
} }
cursor += sizeof(sp_fdbg_symbol_t); return SP_ERROR_NOT_FOUND;
} }
else
{
uint32_t max, iter;
sp_u_fdbg_symbol_t *sym;
sp_u_fdbg_arraydim_t *arr;
uint8_t *cursor = (uint8_t *)(m_pPlugin->debug.symbols);
return SP_ERROR_NOT_FOUND; max = m_pPlugin->debug.syms_num;
for (iter = 0; iter < max; iter++)
{
sym = (sp_u_fdbg_symbol_t *)cursor;
if (sym->ident == SP_SYM_FUNCTION
&& sym->codestart <= addr
&& sym->codeend > addr)
{
*name = m_pPlugin->debug.stringbase + sym->name;
return SP_ERROR_NONE;
}
if (sym->dimcount > 0)
{
cursor += sizeof(sp_u_fdbg_symbol_t);
arr = (sp_u_fdbg_arraydim_t *)cursor;
cursor += sizeof(sp_u_fdbg_arraydim_t) * sym->dimcount;
continue;
}
cursor += sizeof(sp_u_fdbg_symbol_t);
}
return SP_ERROR_NOT_FOUND;
}
} }
int DebugInfo::LookupLine(ucell_t addr, uint32_t *line) int DebugInfo::LookupLine(ucell_t addr, uint32_t *line)

View File

@ -1344,32 +1344,65 @@ void ProfCallGate_End(sp_context_t *ctx)
const char *find_func_name(sp_plugin_t *plugin, uint32_t offs) const char *find_func_name(sp_plugin_t *plugin, uint32_t offs)
{ {
uint32_t max, iter; if (!plugin->debug.unpacked)
sp_fdbg_symbol_t *sym;
sp_fdbg_arraydim_t *arr;
uint8_t *cursor = (uint8_t *)(plugin->debug.symbols);
max = plugin->debug.syms_num;
for (iter = 0; iter < max; iter++)
{ {
sym = (sp_fdbg_symbol_t *)cursor; uint32_t max, iter;
sp_fdbg_symbol_t *sym;
sp_fdbg_arraydim_t *arr;
uint8_t *cursor = (uint8_t *)(plugin->debug.symbols);
if (sym->ident == SP_SYM_FUNCTION max = plugin->debug.syms_num;
&& sym->codestart <= offs for (iter = 0; iter < max; iter++)
&& sym->codeend > offs)
{ {
return plugin->debug.stringbase + sym->name; sym = (sp_fdbg_symbol_t *)cursor;
}
if (sym->ident == SP_SYM_FUNCTION
&& sym->codestart <= offs
&& sym->codeend > offs)
{
return plugin->debug.stringbase + sym->name;
}
if (sym->dimcount > 0)
{
cursor += sizeof(sp_fdbg_symbol_t);
arr = (sp_fdbg_arraydim_t *)cursor;
cursor += sizeof(sp_fdbg_arraydim_t) * sym->dimcount;
continue;
}
if (sym->dimcount > 0)
{
cursor += sizeof(sp_fdbg_symbol_t); cursor += sizeof(sp_fdbg_symbol_t);
arr = (sp_fdbg_arraydim_t *)cursor;
cursor += sizeof(sp_fdbg_arraydim_t) * sym->dimcount;
continue;
} }
}
else
{
uint32_t max, iter;
sp_u_fdbg_symbol_t *sym;
sp_u_fdbg_arraydim_t *arr;
uint8_t *cursor = (uint8_t *)(plugin->debug.symbols);
cursor += sizeof(sp_fdbg_symbol_t); max = plugin->debug.syms_num;
for (iter = 0; iter < max; iter++)
{
sym = (sp_u_fdbg_symbol_t *)cursor;
if (sym->ident == SP_SYM_FUNCTION
&& sym->codestart <= offs
&& sym->codeend > offs)
{
return plugin->debug.stringbase + sym->name;
}
if (sym->dimcount > 0)
{
cursor += sizeof(sp_u_fdbg_symbol_t);
arr = (sp_u_fdbg_arraydim_t *)cursor;
cursor += sizeof(sp_u_fdbg_arraydim_t) * sym->dimcount;
continue;
}
cursor += sizeof(sp_u_fdbg_symbol_t);
}
} }
return NULL; return NULL;