Add instrumentation to JIT invalid instruction errors.

This commit is contained in:
David Anderson 2014-07-14 09:19:44 -07:00
parent 5776909b13
commit 43946e6b6f
4 changed files with 66 additions and 1 deletions

View File

@ -1,5 +1,6 @@
// vim: set ts=4 sw=4 tw=99 noet:
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "engine2.h"
@ -220,3 +221,15 @@ bool SourcePawnEngine2::InstallWatchdogTimer(size_t timeout_ms)
return g_WatchdogTimer.Initialize(timeout_ms);
}
void LogFatalPCodeError(const char *fmt, ...)
{
FILE *fp = fopen("spjit-fatal-log.txt", "at");
if (!fp)
return;
va_list ap;
va_start(ap, fmt);
vfprintf(fp, fmt, ap);
fprintf(fp, "\n");
va_end(ap);
fclose(fp);
}

View File

@ -45,6 +45,8 @@ namespace SourcePawn
};
}
extern void LogFatalPCodeError(const char *fmt, ...);
extern SourcePawn::SourcePawnEngine2 g_engine2;
#endif //_INCLUDE_SOURCEPAWN_ENGINE_2_H_

View File

@ -19,6 +19,7 @@
#include "interpreter.h"
#include "opcodes.h"
#include "watchdog_timer.h"
#include "engine2.h"
#define STACK_MARGIN 64
@ -46,6 +47,10 @@ static inline cell_t *
Jump(const sp_plugin_t *plugin, sp_context_t *ctx, cell_t target)
{
if (!IsValidOffset(target) || uint32_t(target) >= plugin->pcode_size) {
LogFatalPCodeError("[i] invalid jump (name=%s) (target=%d)",
plugin->name,
target
);
ctx->err = SP_ERROR_INVALID_INSTRUCTION;
return NULL;
}
@ -61,6 +66,11 @@ JumpTarget(const sp_plugin_t *plugin, sp_context_t *ctx, cell_t *cip, bool cond)
cell_t target = *cip;
if (!IsValidOffset(target) || uint32_t(target) >= plugin->pcode_size) {
LogFatalPCodeError("[i] invalid jump (name=%s) (cip=%d) (target=%d)",
plugin->name,
cell_t((uint8_t *)cip - plugin->pcode),
target
);
ctx->err = SP_ERROR_INVALID_INSTRUCTION;
return NULL;
}
@ -231,8 +241,14 @@ Interpret(BaseRuntime *rt, uint32_t aCodeStart, cell_t *rval)
cell_t *code = reinterpret_cast<cell_t *>(plugin->pcode);
cell_t *codeend = reinterpret_cast<cell_t *>(plugin->pcode + plugin->pcode_size);
if (!IsValidOffset(aCodeStart) || aCodeStart > plugin->pcode_size)
if (!IsValidOffset(aCodeStart) || aCodeStart > plugin->pcode_size) {
LogFatalPCodeError("[i] invalid cs (name=%s) (cs=%d) (size=%d)",
rt->plugin()->name,
aCodeStart,
plugin->pcode_size
);
return SP_ERROR_INVALID_INSTRUCTION;
}
sp_context_t *ctx = rt->GetBaseContext()->GetCtx();
ctx->err = SP_ERROR_NONE;
@ -248,6 +264,11 @@ Interpret(BaseRuntime *rt, uint32_t aCodeStart, cell_t *rval)
for (;;) {
if (cip >= codeend) {
LogFatalPCodeError("[i] cip overrun (name=%s) (cs=%d) (cip=%d)",
rt->plugin()->name,
aCodeStart,
cell_t(cip - code)
);
ctx->err = SP_ERROR_INVALID_INSTRUCTION;
goto error;
}
@ -764,6 +785,11 @@ Interpret(BaseRuntime *rt, uint32_t aCodeStart, cell_t *rval)
{
cell_t amount = *cip++;
if (!IsValidOffset(amount)) {
LogFatalPCodeError("[i] invalid stack offset (name=%s) (cs=%d) (cip=%d)",
rt->plugin()->name,
aCodeStart,
cell_t(cip - code)
);
ctx->err = SP_ERROR_INVALID_INSTRUCTION;
goto error;
}
@ -970,6 +996,11 @@ Interpret(BaseRuntime *rt, uint32_t aCodeStart, cell_t *rval)
default:
{
LogFatalPCodeError("[i] unknown instruction (name=%s) (cs=%d) (cip=%d)",
rt->plugin()->name,
aCodeStart,
cell_t(cip - code)
);
ctx->err = SP_ERROR_INVALID_INSTRUCTION;
goto error;
}

View File

@ -323,6 +323,12 @@ JitFunction *
Compiler::emit(int *errp)
{
if (cip_ >= code_end_ || *cip_ != OP_PROC) {
LogFatalPCodeError("[j] emit() overran cip (name=%s) (cs=%d) (ce=%d) (cip=%d)",
plugin_->name,
pcode_start_,
cell_t((uint8_t *)cip_ - plugin_->pcode),
cell_t((uint8_t *)code_end_ - plugin_->pcode)
);
*errp = SP_ERROR_INVALID_INSTRUCTION;
return NULL;
}
@ -1345,6 +1351,13 @@ Compiler::emitOp(OPCODE op)
break;
default:
LogFatalPCodeError("[j] unknown opcode (name=%s) (cs=%d) (ce=%d) (cip=%d) (op=%d)",
plugin_->name,
pcode_start_,
cell_t((uint8_t *)cip_ - plugin_->pcode),
cell_t((uint8_t *)code_end_ - plugin_->pcode),
op
);
error_ = SP_ERROR_INVALID_INSTRUCTION;
return false;
}
@ -1544,6 +1557,12 @@ cell_t
Compiler::readCell()
{
if (cip_ >= code_end_) {
LogFatalPCodeError("[j] readCell() overran (name=%s) (cs=%d) (ce=%d) (cip=%d)",
plugin_->name,
pcode_start_,
cell_t((uint8_t *)cip_ - plugin_->pcode),
cell_t((uint8_t *)code_end_ - plugin_->pcode)
);
error_= SP_ERROR_INVALID_INSTRUCTION;
return 0;
}