Пример #1
0
void sigabort(int sig)
{
  /* install the debug hook procedure if this was not done already */
  amx_SetDebugHook(global_amx,prun_Monitor);
  abortflagged=1;
  signal(sig,sigabort); /* re-install the signal handler */
}
Пример #2
0
void pawnStop( void )
{
    chSysLock();
        amx_SetDebugHook( &(g_pawn.amx), aux_Monitor );
    chSysUnlock();
    g_pawn.dontRun = 1;
}
Пример #3
0
PLUGIN_EXPORT int PLUGIN_CALL AmxLoad(AMX *amx) {
  CrashDetect::CreateInstance(amx)->Load();

  amx_SetDebugHook(amx, AmxDebug);
  amx_SetCallback(amx, AmxCallback);
  amx_SetExecErrorHandler(amx, AmxExecError);

  RegisterNatives(amx);
  return AMX_ERR_NONE;
}
Пример #4
0
/* aux_LoadProgram()
 * Load a compiled Pawn script into memory and initialize the abstract machine.
 * This function is extracted out of AMXAUX.C.
 */
int AMXAPI aux_LoadProgram(AMX *amx, char *filename, void *memblock,
                           int AMXAPI (*amx_Debug)(AMX*))
{
  FILE *fp;
  AMX_HEADER hdr;
  int result, didalloc;

  /* open the file, read and check the header */
  if ((fp = fopen(filename, "rb")) == NULL)
    return AMX_ERR_NOTFOUND;
  fread(&hdr, sizeof hdr, 1, fp);
  amx_Align16(&hdr.magic);
  amx_Align32((uint32_t *)&hdr.size);
  amx_Align32((uint32_t *)&hdr.stp);
  if (hdr.magic != AMX_MAGIC) {
    fclose(fp);
    return AMX_ERR_FORMAT;
  } /* if */

  /* allocate the memblock if it is NULL */
  didalloc = 0;
  if (memblock == NULL) {
    if ((memblock = malloc(hdr.stp)) == NULL) {
      fclose(fp);
      return AMX_ERR_MEMORY;
    } /* if */
    didalloc = 1;
    /* after amx_Init(), amx->base points to the memory block */
  } /* if */

  /* read in the file */
  rewind(fp);
  fread(memblock, 1, (size_t)hdr.size, fp);
  fclose(fp);

  /* initialize the abstract machine */
  memset(amx, 0, sizeof *amx);
  amx_SetDebugHook(amx, amx_Debug);     /* set up the debug hook */
  result = amx_Init(amx, memblock);

  /* free the memory block on error, if it was allocated here */
  if (result != AMX_ERR_NONE && didalloc) {
    free(memblock);
    amx->base = NULL;                   /* avoid a double free */
  } /* if */

  return result;
}
Пример #5
0
int aux_LoadProgram(AMX *amx, char *filename, void *memblock)
{
  FILE *fp;
  AMX_HEADER hdr;

  if ((fp = fopen(filename, "rb")) == NULL )
    return AMX_ERR_NOTFOUND;
  fread(&hdr, sizeof hdr, 1, fp);
  amx_Align32((uint32_t*)&hdr.size);
  rewind(fp);
  fread(memblock, 1, (size_t)hdr.size, fp);
  fclose(fp);

  memset(amx, 0, sizeof *amx);
  amx_SetDebugHook(amx, aux_Monitor);
  return amx_Init(amx, memblock);
}
Пример #6
0
int main(int argc,char *argv[])
{
  AMX amx;
  cell ret = 0;
  int err, i;
  clock_t start,end;
  STACKINFO stackinfo = { 0 };
  AMX_IDLE idlefunc;

  if (argc < 2)
    PrintUsage(argv[0]);        /* function "usage" aborts the program */

  #if !defined AMX_NODYNALOAD && defined ENABLE_BINRELOC && (defined __LINUX__ || defined __FreeBSD__ || defined __OpenBSD__)
    /* see www.autopackage.org for the BinReloc module */
    if (br_init(NULL)) {
      char *libroot=br_find_exe_dir("");
      setenv("AMXLIB",libroot,0);
      free(libroot);
    } /* if */
  #endif

  /* Load the program and initialize the abstract machine. */
  err = aux_LoadProgram(&amx, argv[1]);
  if (err != AMX_ERR_NONE) {
    /* try adding an extension */
    char filename[_MAX_PATH];
    strcpy(filename, argv[1]);
    strcat(filename, ".amx");
    err = aux_LoadProgram(&amx, filename);
    if (err != AMX_ERR_NONE)
      PrintUsage(argv[0]);
  } /* if */

  /* To install the debug hook "just-in-time", the signal function needs
   * a pointer to the abstract machine(s) to abort. There are various ways
   * to implement this; here I have done so with a simple global variable.
   */
  global_amx = &amx;
  signal(SIGINT, sigabort);

  /* Initialize two core extension modules (more extension modules may be
   * loaded & initialized automatically as DLLs or shared libraries.
   */
  amx_ConsoleInit(&amx);
  err = amx_CoreInit(&amx);
  ExitOnError(&amx, err);

  /* save the idle function, if set by any of the extension modules */
  if (amx_GetUserData(&amx, AMX_USERTAG('I','d','l','e'), (void**)&idlefunc) != AMX_ERR_NONE)
    idlefunc = NULL;

  for (i = 2; i < argc; i++) {
    if (strcmp(argv[i],"-stack") == 0) {
      uint16_t flags;
      amx_Flags(&amx, &flags);
      if ((flags & AMX_FLAG_NOCHECKS) != 0)
        printf("This script was compiled with debug information removed.\n"
               "Stack monitoring is disfunctional\n\n");
      /* Set "user data" with which the debug monitor can monitor stack usage
       * per abstract machine (in this example, though, there is only one abstract
       * machine, so a global variable would have sufficed).
       */
      memset(&stackinfo, 0, sizeof stackinfo);
      err = amx_SetUserData(&amx, AMX_USERTAG('S','t','c','k'), &stackinfo);
      ExitOnError(&amx, err);
      /* Install the debug hook, so that we can start monitoring the stack/heap
       * usage right from the beginning of the script.
       */
      amx_SetDebugHook(&amx, prun_Monitor);
    } /* if */
  } /* for */

  start=clock();

  /* Run the compiled script and time it. The "sleep" instruction causes the
   * abstract machine to return in a "restartable" state (it restarts from
   * the point that it stopped. This allows for a kind of light-weight
   * cooperative multi-tasking. As native functions (or the debug hook) can
   * also force an abstract machine to "sleep", you can also use it to create
   * "latent functions": functions that allow the host application to continue
   * processing, and/or other abstract machines to run, while they wait for
   * some resource.
   */
  err = amx_Exec(&amx, &ret, AMX_EXEC_MAIN);
  while (err == AMX_ERR_SLEEP) {
    if (idlefunc != NULL) {
      /* If the abstract machine was put to sleep, we can handle events during
       * that time. To save the "restart point", we must make a copy of the AMX
       * (keeping the stack, frame, instruction pointer and other vital
       * registers), but without cloning the entire abstract machine.
       * There should be some criterion on when the abstract machine must be
       * "woken up". In this example run-time, the parameter of the sleep
       * instruction is taken to be a delay in milliseconds. In your own host
       * application, you can choose to wait on a resource/semaphore or other.
       */
      AMX nested_amx = amx;
      clock_t stamp = clock();
      while (((clock() - stamp)*1000)/CLOCKS_PER_SEC < amx.pri
             && (err = idlefunc(&nested_amx,amx_Exec)) == AMX_ERR_NONE)
        /* nothing */;
      ExitOnError(&nested_amx, err);
    } /* if */
    err = amx_Exec(&amx, &ret, AMX_EXEC_CONT);
  } /* while */
  if (idlefunc == NULL || err != AMX_ERR_INDEX)
    ExitOnError(&amx, err);     /* event-driven programs may not have main() */

  /* For event-driven programs, we also need to loop over the idle/monitor
   * function that some extension module installed (this could be the console
   * module, for example). We did this if the main program was put to "sleep",
   * but we do that here too.
   */
  if (idlefunc != NULL) {
    while ((err = idlefunc(&amx,amx_Exec)) == AMX_ERR_NONE)
      /* nothing */;
    ExitOnError(&amx, err);
  } /* if */

  end=clock();

  /* Free the compiled script and resources. This also unloads and DLLs or
   * shared libraries that were registered automatically by amx_Init().
   */
  aux_FreeProgram(&amx);

  /* Print the return code of the compiled script (often not very useful),
   * its run time, and its stack usage.
   */
  if (ret!=0)
    printf("\nReturn value: %ld\n", (long)ret);

  printf("\nRun time:     %.2f seconds\n",(double)(end-start)/CLOCKS_PER_SEC);
  if (stackinfo.maxstack != 0 || stackinfo.maxheap != 0) {
    printf("Stack usage:  %ld cells (%ld bytes)\n",
           stackinfo.maxstack / sizeof(cell), stackinfo.maxstack);
    printf("Heap usage:   %ld cells (%ld bytes)\n",
           stackinfo.maxheap / sizeof(cell), stackinfo.maxheap);
  } /* if */

  #if defined AMX_TERMINAL
    /* This is likely a graphical terminal, which should not be closed
     * automatically
     */
    {
      extern int amx_termctl(int,int);
      while (amx_termctl(4,0))
        /* nothing */;
    }
  #endif

  return 0;
}