235 lines
7.9 KiB
Java
235 lines
7.9 KiB
Java
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is mozilla.org code.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
*/
|
|
|
|
package com.netscape.jsdebugging.jslogger;
|
|
|
|
import netscape.jsdebug.*;
|
|
import netscape.security.PrivilegeManager;
|
|
import com.netscape.jsdebugging.ifcui.Log;
|
|
|
|
class MyInterruptHook
|
|
extends InterruptHook
|
|
implements JSErrorReporter
|
|
{
|
|
public MyInterruptHook(JSLogger logger)
|
|
{
|
|
_logger = logger;
|
|
}
|
|
|
|
public void aboutToExecute(ThreadStateBase debug, PC pc)
|
|
{
|
|
try
|
|
{
|
|
if( ! _enabled(JSLogger.LOGGING_ON) )
|
|
return;
|
|
PrivilegeManager.enablePrivilege("Debugger");
|
|
|
|
if( ! _enabled(JSLogger.TRACE_EXECUTION) )
|
|
return;
|
|
|
|
JSThreadState state = (JSThreadState) debug;
|
|
JSPC jspc = (JSPC) pc;
|
|
// bootstap on the first pass...
|
|
if( null == _lastJSPC )
|
|
_lastJSPC = jspc;
|
|
|
|
String fun = jspc.getScript().getFunction();
|
|
if( null == fun )
|
|
fun = _noFun;
|
|
|
|
String file = jspc.getScript().getURL();
|
|
|
|
|
|
if( _enabled(JSLogger.TRACE_FUNCTION_CALLS) )
|
|
{
|
|
boolean ignoreChain = false;
|
|
CallChain newChain = new CallChain(state);
|
|
|
|
// bootstap on the first pass...
|
|
if( null == _lastChain )
|
|
{
|
|
_lastChain = newChain;
|
|
_lastFunction = fun;
|
|
_lastJSPC = jspc;
|
|
}
|
|
|
|
switch(_lastChain.compare(newChain))
|
|
{
|
|
default:
|
|
case CallChain.EQUAL:
|
|
ignoreChain = true;
|
|
break;
|
|
case CallChain.CALLER:
|
|
// returned
|
|
Log.log(null, _pad(state)+"call to "+_lastFunction+
|
|
" returned to "+fun+" at line: "+
|
|
jspc.getSourceLocation().getLine());
|
|
break;
|
|
case CallChain.CALLEE:
|
|
// calling deeper
|
|
Log.log(null, _pad(state)+_lastFunction+" is calling "+
|
|
fun+ " from line: "+
|
|
_lastJSPC.getSourceLocation().getLine());
|
|
_lastChain = newChain;
|
|
break;
|
|
case CallChain.DISJOINT:
|
|
Log.log(null, _pad(state)+"control jumped to "+fun);
|
|
_lastChain = newChain;
|
|
break;
|
|
}
|
|
if( ! ignoreChain )
|
|
{
|
|
if( _enabled(JSLogger.TRACE_DUMP_CALLSTACKS) )
|
|
_dumpStack(state);
|
|
_lastFunction = fun;
|
|
_lastChain = newChain;
|
|
}
|
|
}
|
|
|
|
if( _enabled(JSLogger.TRACE_EACH_LINE) &&
|
|
(null == _string(JSLogger.IGNORE_SCRIPTS_FROM) ||
|
|
! _string(JSLogger.IGNORE_SCRIPTS_FROM).equals(file)) &&
|
|
(null == _string(JSLogger.LOG_ONLY_SCRIPTS_FROM) ||
|
|
_string(JSLogger.LOG_ONLY_SCRIPTS_FROM).equals(file)) &&
|
|
(null == _string(JSLogger.IGNORE_IN_FUNCTION) ||
|
|
! _string(JSLogger.IGNORE_IN_FUNCTION).equals(fun)) &&
|
|
(null == _string(JSLogger.LOG_ONLY_IN_FUNCTION) ||
|
|
_string(JSLogger.LOG_ONLY_IN_FUNCTION).equals(fun)) )
|
|
{
|
|
if( _lastJSPC.getScript() != jspc.getScript() ||
|
|
_lastJSPC.getSourceLocation().getLine() !=
|
|
jspc.getSourceLocation().getLine() )
|
|
{
|
|
// show info about this line
|
|
String str = _pad(state)+"->"+file+"#"+fun+"#"+
|
|
jspc.getSourceLocation().getLine();
|
|
|
|
// evaluate the expression here if indicated
|
|
String expression = _string(JSLogger.EVAL_EXPRESSION);
|
|
if( null != expression )
|
|
{
|
|
DebugController dc = _logger.getController();
|
|
|
|
JSStackFrameInfo frame =
|
|
(JSStackFrameInfo) state.getCurrentFrame();
|
|
|
|
_evalErrorMsg = null;
|
|
JSErrorReporter oldER = dc.setErrorReporter(this);
|
|
String result =
|
|
dc.executeScriptInStackFrame(frame,
|
|
expression,
|
|
"eval", 1);
|
|
dc.setErrorReporter(oldER);
|
|
if( null != _evalErrorMsg )
|
|
result = _evalErrorMsg;
|
|
|
|
str += " +++ EVAL OF: "+expression+" YIELDS: "+result;
|
|
}
|
|
Log.log(null, str);
|
|
}
|
|
|
|
}
|
|
_lastJSPC = jspc;
|
|
_logger.getController().sendInterrupt();
|
|
}
|
|
catch(Throwable t)
|
|
{
|
|
// eat it...
|
|
Log.log(null, "execption thrown " + t );
|
|
}
|
|
}
|
|
|
|
// implements JSErrorReporter
|
|
public int reportError( String msg,
|
|
String filename,
|
|
int lineno,
|
|
String linebuf,
|
|
int tokenOffset )
|
|
{
|
|
_evalErrorMsg = "!!ERROR!! "+msg;
|
|
return JSErrorReporter.RETURN;
|
|
}
|
|
|
|
private final String _string(int option)
|
|
{
|
|
return _logger.getStringOption(option);
|
|
}
|
|
|
|
private final boolean _enabled(int option)
|
|
{
|
|
return _logger.getBoolOption(option);
|
|
}
|
|
|
|
private final String _pad(JSThreadState state)
|
|
{
|
|
try
|
|
{
|
|
StringBuffer b = new StringBuffer();
|
|
int len = state.getStack().length;
|
|
for(int i = 0; i < len; i++)
|
|
b.append(" ");
|
|
return b.toString();
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
// eat it;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private void _dumpStack(JSThreadState state)
|
|
{
|
|
String pad = _pad(state);
|
|
Log.log(null, pad+"++++BEGIN STACKDUMP:");
|
|
|
|
try
|
|
{
|
|
StackFrameInfo[] stack = state.getStack();
|
|
for(int i = stack.length-1; i >= 0 ; i--)
|
|
{
|
|
JSPC jspc = (JSPC)stack[i].getPC();
|
|
int line = jspc.getSourceLocation().getLine();
|
|
String file = jspc.getScript().getURL();
|
|
String fun = jspc.getScript().getFunction();
|
|
if( null == fun )
|
|
fun = _noFun;
|
|
// Log.log(null, pad+"line: "+line+" fun: "+fun+" file: "+file );
|
|
Log.log(null, pad+file+"#"+fun+"#"+line);
|
|
}
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
// eat it;
|
|
}
|
|
|
|
Log.log(null, pad+"----END STACKDUMP");
|
|
}
|
|
|
|
private JSLogger _logger;
|
|
private CallChain _lastChain = null;
|
|
private String _lastFunction = null;
|
|
private JSPC _lastJSPC = null;
|
|
private String _evalErrorMsg;
|
|
private static final String _noFun = "_TOP_LEVEL_";
|
|
}
|
|
|