Capricorn 76
This tutorial demonstrates how to debug ScriptENGINE applications and requires version 1.4 or later. It is based on the Lua programming libraries.

Test 1

Open console, run a couple of functions and then output some debug information to console.

---------------------------
---------------------------
-- Tutorial: Debugging. Test 1
-- Open console, run a couple of functions and then output some debug information to console.
--
-- Copyright (c) 2006-2008 Capricorn 76 Pty. Ltd.
---------------------------
---------------------------

-- Load the utility script
IApp:loadScript('debuginfo');

---------------------------
-- Example function.
-- NB: Local functions are only accessible within this script-file,
-- and only in scope to functions that follow it.
---------------------------
local function testFunc1(param)
    print('testFunc1:', param);

    showCallstack();
    print('Callstack complete... press any key to continue.');
    IKey:getch();

    showGlobals();
    print('Global variables and functions complete... press any key to continue.');
    IKey:getch();
end

---------------------------
-- PROGRAM ENTRY POINT
---------------------------
-- The ScriptENGINE wil automatically call this function as its entry state into the program.
-- NB: The name of the function should be OnStateRun_[stateName] where the 'stateName' is the name of the script-file for the entry-state.
-- The ScriptENGINE also passes any command line parameters via the function params.
---------------------------
function OnStateRun_test1(param1, param2, param3)

    -- Open the ScriptENGINE console.
    -- Alternatively, you can hold F7 when the program starts...
    IApp:showConsoleWindow();

    -- Run a test function, that will call other functions, and populate the callstack -> giving us something to look at.
    testFunc1('The first debugging test');
end

Test 2

Open console, run a couple of functions and then enter debugger.

---------------------------
---------------------------
-- Tutorial: Debugging. Test 2
-- Open console, run a couple of functions and then enter debugger.
--
-- Copyright (c) 2006-2008 Capricorn 76 Pty. Ltd.
---------------------------
---------------------------

-- Load the utility script
IApp:loadScript('debuginfo');

---------------------------
-- Local functions are only accessible within this script-file,
-- and only in scope to functions that follow it.
---------------------------
local function enterDebugger(param)

    print('enterDebugger:', param);

    ---------------------------
    -- Inform the user that we are entering debug mode.
    ---------------------------
    print('\n\nEntering debug mode. Type \'cont\' to continue normal program execution.');
    print('- Type \'showCallstack()\' to view the current program\'s callstack');
    print('- Type \'print(debug.traceback())\' to view a less detailed view of the callstack');
    print('- Type \'showGlobals()\' to view the program\'s global variables');

    debug.debug();  -- Program control will be halted and passed to the console, waiting for the developer to type 'cont' and continue normal program execution.

    print('Normal program execution recommenced...');
end

function testFunc1(param)
    print('testFunc1:', param);

    -- Call another function with a parameter derived from this function's param.
    enterDebugger('testFunc1->' .. param);
end

---------------------------
-- PROGRAM ENTRY POINT
---------------------------
-- The ScriptENGINE wil automatically call this function as its entry state into the program.
-- NB: The name of the function should be OnStateRun_[stateName] where the 'stateName' is the name of the script-file for the entry-state.
-- The ScriptENGINE also passes any command line parameters via the function params.
---------------------------
function OnStateRun_test2(param1, param2, param3)

    -- Open the ScriptENGINE console.
    -- Alternatively, you can hold F7 when the program starts...
    IApp:showConsoleWindow();

    -- Run a test function, that will call other functions, and populate the callstack -> giving us something to look at.
    testFunc1('Debugging test');

    print('Press any key to exit...');
    IKey:getch();
end

Test 3

Demonstrate the debug.getlocal() and debug.setlocal() functions

---------------------------
---------------------------
-- Tutorial: Debugging. Test 3
-- Demonstrate the debug.getlocal() and debug.setlocal() functions
--
-- Copyright (c) 2006-2008 Capricorn 76 Pty. Ltd.
---------------------------
---------------------------

-- Load the utility script
IApp:loadScript('debuginfo');

---------------------------
-- Local functions are only accessible within this script-file,
-- and only in scope to functions that follow it.
---------------------------
local function enterDebugger(param)

    print('enterDebugger:', param);

    ---------------------------
    -- Inform the user that we are entering debug mode.
    ---------------------------
    print('\n\nEntering debug mode. Type \'cont\' to continue normal program execution.');
    print('- Type \'showCallstack()\' to view the current program\'s callstack');
    print('- Type \'debug.setlocal(3, 1, 99)\'');
    print('  to change the 1st local variable (param) of the 3rd function (enterDebugger) on the callstack to 99.');
    print('- Type \'print(debug.getlocal(3, 1))\' to view the modified value.');
    print('- Interrogate the callstack,');
    print('  to notice that the variable being modified is:');
    print('  \'param\' of function \'enterDebugger\'.');

    debug.debug();  -- Program control will be halted and passed to the console, waiting for the developer to type 'cont' and continue normal program execution.

    print('Normal program execution recommenced...');

    -- Output the modified parameter value.
    -- Notice that it's been changed in the debugger, and is different to the value at the start of this function.
    print('param=', param);
end

function testFunc1(param)
    print('testFunc1:', param);

    -- Call another function with a parameter derived from this function's param.
    enterDebugger('testFunc1->' .. param);
end

---------------------------
-- PROGRAM ENTRY POINT
---------------------------
-- The ScriptENGINE wil automatically call this function as its entry state into the program.
-- NB: The name of the function should be OnStateRun_[stateName] where the 'stateName' is the name of the script-file for the entry-state.
-- The ScriptENGINE also passes any command line parameters via the function params.
---------------------------
function OnStateRun_test3(param1, param2, param3)

    -- Open the ScriptENGINE console.
    -- Alternatively, you can hold F7 when the program starts...
    IApp:showConsoleWindow();

    -- Run a test function, that will call other functions, and populate the callstack -> giving us something to look at.
    testFunc1('Debugging test');

    print('Press any key to exit...');
    IKey:getch();
end

Test 4

Demonstrate the debug.sethook() function

---------------------------
---------------------------
-- Tutorial: Debugging. Test 4
-- Demonstrate the debug.sethook() function
--
-- Copyright (c) 2006-2008 Capricorn 76 Pty. Ltd.
---------------------------
---------------------------

---------------------------
-- Local functions are only accessible within this script-file,
-- and only in scope to functions that follow it.
---------------------------
local function lineHook(hookEvent, lineNumber)

    -- Print debug information from the hook
    local debugInfo = debug.getinfo(2, 'S'); -- The current function running on the stack after the getinfo and lineHook functions
    print('[lineHook] Source:', debugInfo.source, 'Line:', lineNumber);
end

local function testFunc(param)
    print('testFunc:', param);
end

function doTest(param)
    print('doTest:', param);

    -- Call another function with a parameter derived from this function's param.
    print('About to set a debugging hook called \'lineHook\'.');
    print('This hook will be called every time a function is entered...');
    print('Press any key to continue...');
    IKey:getch();

    print('About to run a loop that calls the function \'testFunc\' 5 times.');
    print('Press any key to continue...');
    IKey:getch();

    debug.sethook(lineHook, 'l');   -- Set a debug hook. This can also be called from within the debugger

    local i;
    for i = 1,5 do
        testFunc(i);
    end
end

---------------------------
-- PROGRAM ENTRY POINT
---------------------------
-- The ScriptENGINE wil automatically call this function as its entry state into the program.
-- NB: The name of the function should be OnStateRun_[stateName] where the 'stateName' is the name of the script-file for the entry-state.
-- The ScriptENGINE also passes any command line parameters via the function params.
---------------------------
function OnStateRun_test4(param1, param2, param3)

    -- Open the ScriptENGINE console.
    -- Alternatively, you can hold F7 when the program starts...
    IApp:showConsoleWindow();

    -- Run a test function, that will call other functions, and populate the callstack -> giving us something to look at.
    doTest('Debugging test');

    print('Press any key to exit...');
    IKey:getch();
end

Test 5

Demonstrate the default ScriptENGINE error reporting in debug mode

---------------------------
---------------------------
-- Tutorial: Debugging. Test 5
-- Demonstrate the default ScriptENGINE error reporting
--
-- Copyright (c) 2006-2008 Capricorn 76 Pty. Ltd.
---------------------------
---------------------------

---------------------------
-- PROGRAM ENTRY POINT
---------------------------
-- The ScriptENGINE wil automatically call this function as its entry state into the program.
-- NB: The name of the function should be OnStateRun_[stateName] where the 'stateName' is the name of the script-file for the entry-state.
-- The ScriptENGINE also passes any command line parameters via the function params.
---------------------------
function OnStateRun_test5(param1, param2, param3)

    -- Open the ScriptENGINE console.
    -- Alternatively, you can hold F7 when the program starts...
    IApp:showConsoleWindow();

    -- Run a test function, that will call other functions, and populate the callstack -> giving us something to look at.
    testFunc('Debugging test');

    print('Press any key to exit...');
    IKey:getch();
end

function testFunc(param)
    ---------------------------
    -- This is where we generate the error.
    -- We're attempting to access the graphics engine before it has been initialised.
    ---------------------------
    IGraphics:draw();

    -- Alternatively we can generate Lua errors instead.
    -- error('A Lua error');
end

Copyright © 2006-23 Sep 2009 Capricorn 76 Pty. Ltd. (created on Wed Sep 23 16:49:11 2009)