123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419 |
- /*
- * Copyright (C)2005-2017 Haxe Foundation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
- package cpp.vm;
- /**
- * Parameter describes a function parameter. Instances of this class are
- * embedded in stack frame objects to describe the function parameters that
- * were used in the invocation of the function that defines that stack frame.
- **/
- class Parameter
- {
- public var name(default, null) : String;
- public var value(default, null) : Dynamic;
- public function new(name : String, value : Dynamic)
- {
- this.name = name;
- this.value = value;
- }
- }
- /**
- * StackFrame describes one call stack frame.
- **/
- class StackFrame
- {
- public var fileName(default, null) : String;
- public var lineNumber(default, null) : Int;
- public var className(default, null) : String;
- public var functionName(default, null) : String;
- public var parameters(default, null) : Array<Parameter>;
- public function new(fileName : String, lineNumber : Int,
- className : String, functionName : String)
- {
- this.fileName = fileName;
- this.lineNumber = lineNumber;
- this.className = className;
- this.functionName = functionName;
- this.parameters = new Array<Parameter>();
- }
- }
- /**
- * ThreadInfo describes the state of a single thread.
- **/
- class ThreadInfo
- {
- public static inline var STATUS_RUNNING = 1;
- public static inline var STATUS_STOPPED_BREAK_IMMEDIATE = 2;
- public static inline var STATUS_STOPPED_BREAKPOINT = 3;
- public static inline var STATUS_STOPPED_UNCAUGHT_EXCEPTION = 4;
- public static inline var STATUS_STOPPED_CRITICAL_ERROR = 5;
- // 0 is never a valid thread number
- public var number(default, null) : Int;
- public var status(default, null) : Int;
- // If status is "stopped breakpoint", this is the breakpoint number
- public var breakpoint(default, null) : Int;
- // If status is "critical error", this describes the error
- public var criticalErrorDescription(default, null) : String;
- // Stack will be listed with the lowest frame first
- public var stack(default, null) : Array<StackFrame>;
- public function new(number : Int, status : Int, breakpoint : Int = -1,
- criticalErrorDescription : String = null)
- {
- this.number = number;
- this.status = status;
- this.breakpoint = breakpoint;
- this.criticalErrorDescription = criticalErrorDescription;
- this.stack = new Array<StackFrame>();
- }
- }
- /**
- * This class wraps the hxcpp C++ implementation to provide a Haxe interface
- * to the low level debugging features
- **/
- class Debugger
- {
- public static inline var THREAD_CREATED = 1;
- public static inline var THREAD_TERMINATED = 2;
- public static inline var THREAD_STARTED = 3;
- public static inline var THREAD_STOPPED = 4;
- public static inline var STEP_INTO = 1;
- public static inline var STEP_OVER = 2;
- public static inline var STEP_OUT = 3;
- // This tagging value is returned by getStackVariableValue() and
- // setStackVariableValue if the requested value does not exist at the
- // requested stack frame
- public static var NONEXISTENT_VALUE = new String("NONEXISTENT_VALUE");
- // This tagging value is returned by getStackVariableValue and
- // setStackVariableValue if the stack variable that is being set is on a
- // thread that is running, in which case the set does not take place.
- public static var THREAD_NOT_STOPPED = new String("THREAD_NOT_STOPPED");
- /**
- * Sets the handler callback to be made when asynchronous events occur,
- * specifically, when threads are created, terminated, started, or
- * stopped. The calling thread becomes the "debugger" thread, which means
- * that it will be discluded from any breakpoints and will not be reported
- * on by any thread reporting requests.
- *
- * Be aware that this callback is made asynchronously and possibly by
- * multiple threads simultaneously.
- *
- * Setting this to null prevents further callbacks.
- *
- * Throws a string exception if the program does not support debugging
- * because it was not compiled with the HXCPP_DEBUGGER flag set.
- *
- * @param handler is a function that will be called back by asynchronous
- * thread events. Note that this function is called directly from
- * the thread experiencing the event and the handler should return
- * quickly to avoid blocking the calling thread unnecessarily.
- * The parameters to handler are:
- * - threadNumber, the thread number of the event
- * - event, one of THREAD_CREATED, THREAD_TERMINATED,
- * THREAD_STARTED, or THREAD_STOPPED
- * - stackFrame, the stack frame number at which the thread is stopped,
- * undefined if event is not THREAD_STOPPED
- * - className, the class name at which the thread is stopped,
- * undefined if event is not THREAD_STOPPED
- * - functionName, the function name at which the thread is
- * stopped, undefined if event is not THREAD_STOPPED
- * - fileName, the file name at which the thread is stopped,
- * undefined if event is not THREAD_STOPPED
- * - lineNumber, the line number at which the thread is stopped,
- * undefined if event is not THREAD_STOPPED
- **/
- public static function setEventNotificationHandler(
- handler : Int -> Int -> Int -> String -> String -> String -> Int -> Void)
- {
- untyped __global__.__hxcpp_dbg_setEventNotificationHandler(handler);
- }
- /**
- * This can be called to turn off (and then back on) all stopping of
- * debugged threads temporarily. It should only be used by classes that
- * actually implement the debugger to hide themselves from the debugger as
- * necessary.
- **/
- public static function enableCurrentThreadDebugging(enabled : Bool)
- {
- untyped __global__.__hxcpp_dbg_enableCurrentThreadDebugging(enabled);
- }
- /**
- * Returns the thread number of the calling thread.
- *
- * @return the thread number of the calling thread.
- **/
- public static function getCurrentThreadNumber() : Int
- {
- return untyped __global__.__hxcpp_dbg_getCurrentThreadNumber();
- }
- /**
- * Returns the set of source files known to the debugger. This is a copy
- * of the original array and could be quite large. The caller should
- * cache this value to avoid multiple copies needing to be made.
- *
- * @return the set of source files known to the debugger.
- **/
- public static function getFiles() : Array<String>
- {
- return untyped __global__.__hxcpp_dbg_getFiles();
- }
- /**
- * Returns the full paths of the set of source files known to the debugger.
- * This is a copy of the original array and could be quite large.
- * It is possible that this set will be empty, in which case the full paths are not known.
- * The index of these files matches the index from "getFiles", so the full path for
- * a given short path can be calculated.
- *
- * @return the known full paths of the set of source files
- **/
- public static function getFilesFullPath() : Array<String>
- {
- return untyped __global__.__hxcpp_dbg_getFilesFullPath();
- }
- /**
- * Returns the set of class names of all classes known to the debugger.
- * This is a copy of the original array and could be quite large. The
- * caller should cache this value to avoid multiple copies needing to be
- * made.
- *
- * @return the set of class names of all classes known to the debugger.
- **/
- public static function getClasses() : Array<String>
- {
- return untyped __global__.__hxcpp_dbg_getClasses();
- }
- /**
- * Returns a ThreadInfo object describing every thread that existed at the
- * moment that the call was made, except for the debugger thread.
- **/
- public static function getThreadInfos() : Array<ThreadInfo>
- {
- return untyped __global__.__hxcpp_dbg_getThreadInfos();
- }
- /**
- * Returns a ThreadInfo object describing a single thread, or null if
- * there is no such thread or the thread queried about was the debugger
- * thread and unsafe was not true.
- **/
- public static function getThreadInfo(threadNumber : Int,
- unsafe : Bool) : ThreadInfo
- {
- return untyped __global__.__hxcpp_dbg_getThreadInfo
- (threadNumber, unsafe);
- }
- /**
- * Adds a new file:line breakpoint. The breakpoint number of the newly
- * added breakpoint is returned.
- **/
- public static function addFileLineBreakpoint(file : String,
- line : Int) : Int
- {
- return untyped __global__.__hxcpp_dbg_addFileLineBreakpoint
- (file, line);
- }
- /**
- * Adds a new class:function breakpoint. The breakpoint number of the
- * newly added breakpoint is returned.
- **/
- public static function addClassFunctionBreakpoint(className : String,
- functionName : String) : Int
- {
- return untyped __global__.__hxcpp_dbg_addClassFunctionBreakpoint
- (className, functionName);
- }
- /**
- * Deletes a breakpoint, or all breakpoints.
- **/
- public static function deleteBreakpoint(number : Null<Int>)
- {
- if (number == null) {
- untyped __global__.__hxcpp_dbg_deleteAllBreakpoints();
- }
- else {
- untyped __global__.__hxcpp_dbg_deleteBreakpoint
- (cast (number, Int));
- }
- }
- /**
- * Breaks all threads except the debugger thread (which should be the same
- * as the calling thread!).
- *
- * If `wait` is true, waits up to 2 seconds for all threads to be broken.
- * Threads which are in blocking system calls and cannot break after 2
- * seconds remain running when this function returns.
- **/
- public static function breakNow(wait : Bool = true)
- {
- untyped __global__.__hxcpp_dbg_breakNow(wait);
- }
- /**
- * Continue execution of all stopped threads. If specialThreadNumber
- * is a valid thread number, then it will be continued past
- * `continueCount` breakpoints instead of just 1 like all of the other
- * threads.
- **/
- public static function continueThreads(specialThreadNumber : Int,
- continueCount : Int)
- {
- untyped __global__.__hxcpp_dbg_continueThreads
- (specialThreadNumber, continueCount);
- }
- /**
- * Single steps the given thread.
- **/
- public static function stepThread(threadNumber : Int,
- stepType : Int,
- stepCount : Int = 1)
- {
- untyped __global__.__hxcpp_dbg_stepThread
- (threadNumber, stepType, stepCount);
- }
- /**
- * Returns the list of local variables (including "this", function
- * arguments, and local variables) visible to the given thread at the
- * given stack frame.
- *
- * Returns a list with a single entry, THREAD_NOT_STOPPED, if the
- * thread is not stopped and thus variables cannot be fetched and
- * unsafe is not true.
- *
- * @return the list of local variables (including "this", function
- * arguments, and local variables) visible to the given thread at
- * the given stack frame.
- **/
- public static function getStackVariables(threadNumber : Int,
- stackFrameNumber : Int,
- unsafe : Bool) : Array<String>
- {
- return untyped __global__.__hxcpp_dbg_getStackVariables
- (threadNumber, stackFrameNumber, unsafe, THREAD_NOT_STOPPED);
- }
- /**
- * Returns the value of a stack variable, or NONEXISTENT_VALUE if the
- * requested value does not exist. If the thread is actively running
- * and unsafe is not true, returns THREAD_NOT_STOPPED.
- **/
- public static function getStackVariableValue(threadNumber : Int,
- stackFrameNumber : Int,
- name : String,
- unsafe : Bool) : Dynamic
- {
- return untyped __global__.__hxcpp_dbg_getStackVariableValue
- (threadNumber, stackFrameNumber, name, unsafe, NONEXISTENT_VALUE,
- THREAD_NOT_STOPPED);
- }
- /**
- * Sets the value of a stack variable and returns that value. If the
- * variable does not exist, on the stack, this function returns
- * NONEXISTENT_VALUE. If the thread is actively running and unsafe is not
- * true, returns THREAD_NOT_STOPPED, and the value is not set.
- **/
- public static function setStackVariableValue(threadNumber : Int,
- stackFrameNumber : Int,
- name : String,
- value : Dynamic,
- unsafe : Bool) : Dynamic
- {
- return untyped __global__.__hxcpp_dbg_setStackVariableValue
- (threadNumber, stackFrameNumber, name, value, unsafe,
- NONEXISTENT_VALUE, THREAD_NOT_STOPPED);
- }
- // The hxcpp runtime calls back through these functions to create Haxe
- // objects as needed, which allows the C++ implementation code to create
- // Haxe objects without having to actually know the structure of those
- // objects
- private static function __init__()
- {
- untyped __global__.__hxcpp_dbg_setNewParameterFunction
- (
- function (name : String, value : Dynamic) : Dynamic {
- return new Parameter(name, value);
- }
- );
- untyped __global__.__hxcpp_dbg_setNewStackFrameFunction
- (
- function (fileName : String, lineNumber : Int,
- className : String, functionName : String)
- {
- return new StackFrame(fileName, lineNumber,
- className, functionName);
- }
- );
- untyped __global__.__hxcpp_dbg_setNewThreadInfoFunction
- (
- function (number : Int, status : Int, breakpoint : Int,
- criticalErrorDescription : String) : Dynamic {
- return new ThreadInfo(number, status, breakpoint,
- criticalErrorDescription);
- }
- );
- untyped __global__.__hxcpp_dbg_setAddParameterToStackFrameFunction
- (
- function(inStackFrame : Dynamic, inParameter : Dynamic) {
- var stackFrame : StackFrame = cast inStackFrame;
- var parameter : Parameter = cast inParameter;
- stackFrame.parameters.push(parameter);
- }
- );
- untyped __global__.__hxcpp_dbg_setAddStackFrameToThreadInfoFunction
- (
- function(inThreadInfo : Dynamic, inStackFrame : Dynamic) {
- var threadInfo : ThreadInfo = cast inThreadInfo;
- var stackFrame : StackFrame = cast inStackFrame;
- threadInfo.stack.push(stackFrame);
- }
- );
- }
- }
|