Skip to content

Documentation

Besnard Jean-Baptiste edited this page Apr 15, 2014 · 15 revisions

Class : ngdbmi

### Events:


  • Event app(line): Called on application output
    • line: application output line
ngdbmi.on("app", function( line )
{
        /* Called on application output */
        console.log( "APP>" + line );
});

  • Event gdb(line): Called on GDB output
    • line: gdb output line
ngdbmi.on("gdb", function( line )
{
        /* Called on GDB output */
        console.log( "GDB>" + line );
});

  • Event notify(state): Called on notification events with a state
    • state: GDB state when handler is triggered
ngdbmi.on("notify", function( state )
{
        /* Called each time GDB triggers a
           notify event with the associated state */
        console.log( "NOTIFY>" + JSON.stringify(state) );
});

  • Event ready(state): Called when gdb is ready for command (previous command state in param)
    • state: GDB state when handler is triggered
ngdbmi.on("ready", function( state )
{
        /* Called each time GDB is ready with
           the associated state (reason why GDB is ready) */
        console.log( "READY>" + JSON.stringify(state) );
});

  • Event gdbError(state): Called when GDB encounters an error (for example bad command)
    • state: gdb state when handler is triggered
gdb.on("gdbError", function( state )
{
        /* Here GDB encountered an error
           such as a bad argument details are in state */
        console.log( "ERROR>" + JSON.stringify(state) );
});

  • Event close(return_code, signal): Called when wrapped GDB instance has exited
    • return_code: gdb return code
    • signal: signal caught by GDB null if none
gdb.on("close", function( return_code, signal )
{
        /* Here GDB instance has ended and
           will take no further commands */
        console.log( "GDB closed RET=" + return_code );
});

Methods:


  • ngdbmi([command_and_args], [options], [gdbWrapper] ): ngdbmi constructor
  • [command_and_args]: Command to execute and its arguments
  • [options]: some configuration modifiers in the following list:
    • gdb_log_max_len : maximum length to keep (in line) for GDB output
    • app_log_max_len : maximum length to keep (in line) for program output
  • [gdbWrapper]: GDB wrapper to be used (advanced use)
ngdbmi = require("ngdbmi");
/* Just a running gdb with no app */
var gdb1 = new ngdbmi();
/* A gdb associated to ./a.out with args foo and bar (not running) */
var gdb2 = new ngdbmi("./a.out foo bar");
/* A gdb associated to ./a.out with args foo and bar and some params (not running) */
var gdb2 = new ngdbmi("./a.out foo bar",{gdb_log_max_len : 1024, app_log_max_len: 1024});

  • ngdbmi.command( command, [handler], [args] ): execute a command in the target GDB
    • command: command to be run (see command list section for further details)
    • [handler]: function to be called when GDB is ready again
    • [args]: argument object, sometimes required -> see command list
ngdbmi.command("run", function( state )
{
        /* Here we have control when
           gdb is ready again */
});

  • ngdbmi.gdbOutput( [n] ): get the n last lines from GDB
    • [n]: number of lines to be retrieved (max is set by gdb_log_max_len in gdbmi configuration) but you can get less
console.log( ngdbmi.gdbOutput(32) );

  • ngdbmi.programOutput( [n] ): get the n last lines from target app
    • [n]: number of lines to be retrieved (max is set by app_log_max_len in gdbmi configuration) but you can get less
console.log( ngdbmi.programOutput(32) );

GDB commands and asynchronism

ngdbmi is simply a wrapper arround a GDB instance. It allows the interaction with this instance through node.js while retrieving output information in JSON. Thus when using ngdbmi you are directly using a GDB instance with no state handling at all. As a consequence we rely on an event based approach to signal when the debugger is ready to receive commands. To do so each command is provided with a handler which is called when the program is back in interactive mode.


Example:

/* Load the ngdbmi module */
ngdbmi = require("ngdbmi");
/* Lauch a gdb instance on a.out */
gdb = new ngdbmi("./a.out");

gdb.command("run", function(state)
{
   /* Here as we set no breakpoint
      we will only be notified when
      gdb becomes interactive :
        * Program ended
        * Program crashed */
});

However as sometimes an user would like to be notified when GDB is ready for command for example if we rely on a socket IO mode or whatever, you can register yourself to the "ready" event which is emitted each time GDB goes interactive


Example:

ngdbmi = require("ngdbmi");
/* Create a new GDB instance over ./a.out with args foo and bar */
gdb = new ngdbmi("./a.out");
/* Gdb ready event */
gdb.on("ready", function( state )
{
	console.log( JSON.stringify(state, null, "\t") );
});
/* Launch it ! */
gdb.command("run", function()
{
	gdb.command("exit");
});

Producing the following output when everything goes well:

-exec-run 
{
	"state": "running",
	"status": {
		"id": "1",
		"group-id": "i1"
	}
}
{
	"state": "running",
	"status": {
		"thread-id": "all"
	}
}
{
	"state": "stopped",
	"status": {
		"reason": "exited-normally"
	}
}
-gdb-exit 
{
	"state": "exit",
	"status": {}
}

As a consequence just like in a gdb session you have to make sure commands are entered in a sequence when the GDB instance is ready.

Command List

This list directly match the one of the GDB/MI (see here) thus it can be consulted if more details are required.

For each command the basic pattern is the following:

ngdbmi.command(commandName, function( state )
{
    /* Handler called when ready with GDB state
       in parameter */
},{
   /* Arguments */
   argName : "ArgValue",
   ...
});

Handlers and parameters can be optional for some calls however some commands require arguments to be valid.

In the following list all the commands currently implemented and an explanation of their parameters. Optional ones are in brackets and it is precised when a parameter has to be associated with a values (and thus in not solely a Boolean switch).

Process Management


  • execInterrupt (-exec-interrupt): Interrupts the execution of a program running asynchronously

  • interrupt (added by ngdbmi): Sends a SIGINT to every child process thus interrupting their execution
    • [pid]: pid of one of the thread groups (if node provided all are interrupted)

Sample output when called:

{
	"state": "stopped",
	"status": {
		"reason": "signal-received",
		"signal-name": "SIGINT",
		"signal-meaning": "Interrupt",
		"frame": {
			"addr": "0x00007ffff7ad28c0",
			"func": "nanosleep",
			"args": [],
			"from": "/lib/x86_64-linux-gnu/libc.so.6"
		},
		"thread-id": "1",
		"stopped-threads": "all",
		"core": "6"
	}
}

  • run (-exec-run): Launch the debuggee (same as gdb run)

Sample output when called:

(READY HANDLER)
{
    "state": "running",
    "status": {
        "id": "1",
        "group-id": "i1"
    }
}
(READY HANDLER)
{
    "state": "running",
    "status": {
        "thread-id": "all"
    }
}
(run handler if program exits normally)
{
	"state": "stopped",
	"status": {
		"reason": "exited-normally"
	}
}
(run handler on a segfault)
{
	"state": "stopped",
	"status": {
		"reason": "signal-received",
		"signal-name": "SIGSEGV",
		"signal-meaning": "Segmentation fault",
		"frame": {
			"addr": "0x00000000004004c4",
			"func": "main",
			"args": []
		},
		"thread-id": "1",
		"stopped-threads": "all",
		"core": "7"
	}
}
(run handler on breakpoint)
{
    "state": "stopped",
    "status": {
        "reason": "breakpoint-hit",
        "disp": "keep",
        "bkptno": "1",
        "frame": {
            "addr": "0x0000000000400494",
            "func": "bar",
            "args": [],
            "file": "./test.c",
            "fullname": "/repo/ngdb/test.c",
            "line": "6"
        },
        "thread-id": "1",
        "stopped-threads": "all",
        "core": "1"
    }
}

  • step (-exec-step): Execute until next instruction (same as gdb step)

Sample output when called:

{
	"state": "stopped",
	"status": {
		"reason": "end-stepping-range",
		"frame": {
			"addr": "0x00000000004004f4",
			"func": "foo",
			"args": []
		},
		"thread-id": "1",
		"stopped-threads": "all",
		"core": "6"
	}
}

  • stepInstruction (-exec-step-instruction):

Sample output when called:

{
	"state": "stopped",
	"status": {
		"reason": "end-stepping-range",
		"frame": {
			"addr": "0x00000000004004f4",
			"func": "foo",
			"args": []
		},
		"thread-id": "1",
		"stopped-threads": "all",
		"core": "6"
	}
}

  • next (-exec-next): Go to next instruction be won't enter a function (same as gdb next)

Sample output when called:

{
	"state": "stopped",
	"status": {
		"reason": "end-stepping-range",
		"frame": {
			"addr": "0x00000000004004f4",
			"func": "foo",
			"args": []
		},
		"thread-id": "1",
		"stopped-threads": "all",
		"core": "6"
	}
}

  • jump (-exec-jump): resume execution at the location provided in argument
    • location (value required): where to resume the execution (see here for location syntax)

Sample output when called:

(READY HANDLER)
{
	"state": "running",
	"status": {}
}
(READY HANDLER)
{
	"state": "running",
	"status": {
		"thread-id": "all"
	}
}

  • execUntil (-exec-until): continue execution until reaching this location
    • location (value required): where to stop the execution (see here for location syntax)

Sample output when called:

(READY HANDLER)
{
	"state": "running",
	"status": {}
}
(READY HANDLER)
{
	"state": "running",
	"status": {
		"thread-id": "1"
	}
}
(execUntil handler)
{
	"state": "stopped",
	"status": {
		"reason": "location-reached",
		"frame": {
			"addr": "0x00000000004004f4",
			"func": "foo",
			"args": []
		},
		"thread-id": "1",
		"stopped-threads": "all",
		"core": "5"
	}
}

  • continue (-exec-continue): Continue the execution until something happens (end or crash)
    • [id] (value required): thread to continue

Sample output when called:

(READY HANDLER)
{
	"state": "running",
	"status": {}
}
(READY HANDLER)
{
	"state": "running",
	"status": {
		"thread-id": "1"
	}
}

  • finish (-exec-finish): execute the rest of the function

Sample output when called:

{
	"state": "stopped",
	"status": {
		"reason": "function-finished",
		"frame": {
			"addr": "0x0000000000400500",
			"func": "foo",
			"args": [],
			"file": "./test.c",
			"fullname": "/repo/ngdb/test.c",
			"line": "11"
		},
		"thread-id": "1",
		"stopped-threads": "all",
		"core": "0"
	}
}

Breakpointing


  • breakAfter (-break-after):
    • id (value required):
    • count (value required):

  • breakCommand (-break-command):
    • id (value required):
    • command (value required):

  • breakCondition (-break-condition):
    • id (value required):
    • expr (value required):

  • breakDelete (-break-delete):
    • id (value required):

  • breakDisable (-break-disable):
    • id (value required):

  • breakEnable (-break-enable):
    • id (value required):

  • breakInfo (-break-info):
    • id (value required):

  • breakList (-break-list):

  • breakInsert (-break-insert):
    • [temporary] (Boolean switch):
    • [hardware] (Boolean switch):
    • [force] (Boolean switch):
    • [disabled] (Boolean switch):
    • [tracepoint] (Boolean switch):
    • [condition] (value required):
    • [ignoreCount] (value required):
    • [threadId] (value required):
    • location (value required):

  • dprintf (-dprintf-insert):
    • [temporary] (Boolean switch):
    • [force] (Boolean switch):
    • [disabled] (Boolean switch):
    • [condition] (value required):
    • [ignoreCount] (value required):
    • [threadId] (value required):
    • location (value required):
    • format (value required):

  • breakPasscount (-break-passcount):
    • id (value required):
    • count (value required):

  • watch (-break-watch):
    • [read] (Boolean switch):
    • [readWrite] (Boolean switch):
    • location (value required):

Catchpoints


  • catchLoad (-catch-load):
    • [temporary] (Boolean switch):
    • [disabled] (Boolean switch):
    • [regExp] (value required):

  • catchUnload (-catch-unload):
    • [temporary] (Boolean switch):
    • [disabled] (Boolean switch):
    • [regExp] (value required):

Program Context


  • setArg (-exec-arguments):
    • arg (value required):

  • setWorkingDirectory (-environment-cd):
    • path (value required):

  • setSourcePath (-environment-directory):
    • [reset] (Boolean switch):
    • path (value required):

  • setObjectPath (-environment-path):
    • [reset] (Boolean switch):
    • path (value required):

  • pwd (-environment-pwd):

Thread Management


  • threadInfo (-thread-info):
    • [id] (value required):

  • threadListIds (-thread-list-ids):

  • threadSelect (-thread-select):
    • id (value required):

Frame Management


  • frame (-stack-info-frame):

  • stackDepth (-stack-info-depth):
    • [maxDepth] (value required):

  • stackListArguments (-stack-list-arguments):
    • [skip] (Boolean switch):
    • print (value required):
    • [frameBoundaries] (value required):

  • stackListFrames (-stack-list-frames):
    • [frameBoundaries] (value required):

  • stackListLocals (-stack-list-locals):
    • [skip] (Boolean switch):
    • print (value required):

  • stackListVariables (-stack-list-variables):
    • [skip] (Boolean switch):
    • print (value required):

  • frameSelect (-stack-select-frame):
    • id (value required):

TODO variables

TODO Data

TODO Tracepoints

TODO query

File Commands


  • symbolList (-symbol-list-lines):
    • filename (value required):

  • executableAndSymbols (-file-exec-and-symbols):
    • filename (value required):

  • executable (-file-exec-file):
    • filename (value required):

  • symbols (-file-symbol-file):
    • filename (value required):

  • sourceCtx (-file-list-exec-source-file):

  • listSourceFiles (-file-list-exec-source-files):

Target Manipulation


  • attach (-target-attach):
    • target (value required):

  • detach (-target-detach):
    • target (value required):

  • disconnect (-target-disconnect):

  • download (-target-download):

  • targetSelect (-target-select):
    • type (value required):
    • param (value required):

  • commandExists (-info-gdb-mi-command):
    • command (value required):

TODO File Transfers

Support Commands


  • listFeature (-list-features):

  • listTargetFeature (-list-target-features):

Miscellaneous Commands


  • exit (-gdb-exit):

  • set (-gdb-set):
    • name (value required):
    • value (value required):

  • show (-target-select):
    • name (value required):

  • version (-gdb-version):

  • listThreadGroups (-list-thread-groups):
    • [available] (Boolean switch):
    • [recurse] (Boolean switch):
    • [group] (value required):

  • os (-info-os):
    • [type] (value required):

  • addInferior (-add-inferior):

  • exec (-interpreter-exec):
    • interpreter (value required):
    • command (value required):

  • ttySet (-inferior-tty-set):
    • tty (value required):

  • ttyShow (-inferior-tty-show):

  • enableTimings (-enable-timings):
    • [value] (value required):

Advanced Use