/* -*- Mode: C; c-file-style: "gnu" -*-
   abort.c -- our own version of abort that calls the vm hook.
   Created: Chris Toshok <toshok@hungry.com>, 15-Aug-1997
*/
/*
  This file is part of Japhar, the GNU Virtual Machine for Java Bytecodes.
  Japhar is a project of The Hungry Programmers, GNU, and OryxSoft.

  Copyright (C) 1997, 1998, 1999 The Hungry Programmers

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "jniint.h"
#include "native-threads.h"
#include "signals.h"
#include "interp.h"
#include "exceptions.h"

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdlib.h>
#include <assert.h>

#ifndef PROFILING
void
abort(void)
{
  JNIEnv *env = THREAD_getEnv();
  if (env)
    {
      HungryJNIEnv *henv = (HungryJNIEnv*)env;
      HungryJavaVM *vm = henv->_vm;

      if (vm->abort)
	{
	  (*vm->abort)();
	  return;
	}
    }

#ifdef DEBUG
  SIGNAL_crash();
#else
  exit(-1);
#endif
}
#endif

void
fatal_signal_handler(int signal)
{
  JNIEnv *env = THREAD_getEnv();
  HungryJNIEnv *henv = (HungryJNIEnv*)env;
  JThreadInfo* thread_info = henv->_java_info;
  StackFrame *frame = TOPFRAME(thread_info);

  while (frame < thread_info->stack_highwater)
    {
      if (frame->flags & FRAME_NATIVE)
	{
	  fprintf (stderr, "native frame:\t%s.%s\n",
		   getClassName(env, METHOD(frame)->clazz),
		   METHOD(frame)->name);
	}
      else 
	{
	  int line_number = method_pc_to_line_number(env, METHOD(frame), PC(frame));;
	  if (-1 == line_number)
	    fprintf (stderr, "java frame:\t%s.%s (pc = %d)\n",
		     getClassName(env, METHOD(frame)->clazz),
		     METHOD(frame)->name, PC(frame));
	  else
	    fprintf (stderr, "java frame:\t%s.%s (%d, pc = %d)\n",
		     getClassName(env, METHOD(frame)->clazz),
		     METHOD(frame)->name, line_number, PC(frame));
	}

      frame = get_frame_parent(frame);
    }

#ifdef DEBUG
  SIGNAL_crash();
#else
  exit(-1);
#endif
}
