Scope

A simple GDB front-end

"We are like dwarfs sitting on the shoulders of giants."
-- Bernard of Chartres


Contents


About

Scope is a graphical GDB front-end with the normal functions you would expect (stepping, breakpoints...), and a few notable features:

Scope is currently implemented as a Geany plugin.

"Source files" refers to the file types supported by gdb: C/C++, D, Objective C, Fortran, Java, Pascal, Assembler and Ada (ATM).

Trivial topics that require neither description nor comment are not included in this document.


Requirements

Geany 1.22 or later and the respective libraries, including VTE under *nix.

GDB 7.3 or later.

win~1: XP or later.

GDB manual (recommended).


Quick start

From the main Geany menu, invoke Debug --> Setup Program (or Tools --> Debug --> Setup Program, if there's no Debug in the main menu).
Choose some small executable file compiled with gdb debug information.
Check Temporary breakpoint at and press OK.
Invoke Debug --> Run/Continue.

If everything went all right, several things will happen:
- A colored Load label will appear shortly on the right of Geany status bar
- The message window will be shown (if hidden) and the Debug page will be focused
- The cursor be positioned at the first line of code, opening the corresponding source file if neccessary
- The first line of code will be marked with brown arrow in the markers margin, or with brown background
- All source files will be marked as read-only (their tabs will turn green)
- The Load label will be replaced with a color-less Debug.

That's it, you are debugging. Try the other Debug menu commands, select the Debug subpages from the lower Geany panel etc.


Interface

Consists of:

Debug menu

Setup Program

You can use non-existent Executable, Working dir and Run Script, and create them later.

Arguments are in gdb syntax.

Environment is one var=value per line.

Load script is a gdb script file to be executed when gdb is loaded, before running the program (see Run/Continue). If this script contains a gdb run command, it should contain at least one breakpoint command as well, because all Scope breakpoints are applied after the program is loaded - and it may be loaded by the script.

Auto run program/exit gdb - with this box unchecked, the first Run/Continue will load and setup the program without running it; and when the program terminates, gdb will not be unloaded. This is useful if you want to run a program several times without reloading, for example to run it unmodified with different sets of input data.

Non-stop mode - gdb non-stop mode. You'd better activate gdb asynchronous mode from Scope preferences to take advantage of this.

Temporary breakpoint at - set a temporary breakpoint after the program is loaded. If you leave the text field empty, Scope will try to detect the 1st line of code and place a breakpoint on it. Any breakpoint options and location are allowed, for example main for C/C++ programs. Since setting a breakpoint requires a program, temporary breakpoint will be disabled if both Executable and Load script are empty.

Delete all breakpoints, watches and inspects - usually when setting up a new program. Scope will ask you to confirm.

Update all views - update all relevant debug subpages when the current thread stops, or a different thread is selected. By default, only the current subpage is updated.

Using Locale text mode requires the same code page for Geany/Scope and the program being debugged.

Unchecking Display member and argument names or using Name=value are not guaranteed to work; single-quoted strings ending with backslash will fail. GDB "set print" commands also affect display.

Import - get Executable and Working dir from the second Geany Execute command (from Tools -> Set Build Commands).

When you start Geany, or open/close a project, Scope will try to load the debugging settings for a program that matches the second Execute command, if any [N]. The command will not be expanded. Letter case will be ignored under win~1.

Run/Continue [NHD]

Not debugging state (first run):
- Checks the Program and Working dir, if any - they must exist and be user-executable at this point
- Checks the Load script, if any - it must exist and be readable
- Loads gdb
- Setups the asynchronous and/or non-stop modes
- Loads the Program, if any
- Executes the Load script, if any
- If either a program was loaded, or a load script was executed without errors:
• applies any breakpoints and inspects marked as Apply on Run
• applies the temporary breakpoint, if any
• runs the program if, and only if:
- Auto run/exit is checked
- at least 1 breakpoint was applied
- there were no errors in any of the previous steps.

Hang state: -exec-run. The temporary breakpoint, if any, will not be applied.
Debug/Assem: -exec-continue.

Run to Cursor [D]

scope_goto_cursor=0: -exec-until with the current filename:line
scope_goto_cursor=1: set temporary breakpoint at the current position and -exec-continue.

Run to Source [D]

Assem state only: -exec-step. See gdb step description.

Step Into / Step Over [D]

Debug state: -exec-step / -exec-next.
Assem state: -exec-step-instruction / -exec-next-instruction.

Terminate [^N]

Busy state: kill gdb, even if Auto Run/exit is unchecked. If you want to kill the program only, switch to Threads and use Terminate or Send Signal.

Debug or Ready state with Auto Run/Exit off: gdb kill command.

Otherwise: -gdb-exit.

GDB Command [^N]

Commands starting with 0<digit> are used internally by Scope and will be blocked.

Scope tries to keep track of the current gdb thread, and to emit a -thread-select command on Send/Busy if the gdb thread does not match the one (if any) selected in Threads. Tracking the current gdb frame asynchronously is impossible, so you must use a gdb frame selection command or --frame for the non-zero frames.

Writing a full combo box for multi-line text is outside the scope of this project.

Reset Markers

Synchronizes the breakpoint and execution point markers for the current file with the Scope data. They can become out of sync if you Save as a file with markers, set a source file type to non-source and edit it, and possibly in other situations.

Cleanup Files

While debugging a program, Scope will automatically open the source files required to show the current execution point(s). This command closes such files.

Debug panel

The sort orders and column widths are not saved. However, the breakpoints and watches are saved in their current order.

Sorting by file name (including breakpoint location) uses the full locale name, so the order may be different from the displayed UTF-8 base names.

Program Terminal

Will be disabled if a pseudo-tty can not be created.

May be displayed either in a Debug panel tab or as a separate window.

Window:
Auto showSwitch to separate window display on program startup (when the first thread is created).
Auto hideSwitch to Debug panel tab display on program shutdown (when the last thread is exited).
Show on ErrorSwitch to separate window display when a thread group is exited with a non-zero status.
Not reliable if combined with Auto Hide on multi-thread-group programs.

Threads

The thread list is updated by asynchronous gdb messages. Normally you should not need to refresh it, and Refresh won't append or remove threads, only update the current ones.

Synchronize - refresh and select the current gdb thread. Shift-click: -thread-select.

Interrupt - *nix: SIGINT, win~1: DebugBreakProcess.

Terminate - *nix: SIGTERM, win~1: TerminateProcess.

Both Interrupt and Terminate require an extra Step deliver a signal/*process to a stopped thread, and an extra Step to terminate a process.

Select on:
RunningSelect a stopped thread (if any) when the current thread becomes running. Useful when starting/stopping lots of threads, but may be annoying in other situations - for example, if you are single-stepping a thread, and another stopped thread exists, it'll be selected on each step.
StoppedSelect a thread when it stops (if there is no stopped thread already selected).
ExitedSelect a stopped thread (if any) when the current thread is exited.
FollowFollow gdb =thread-selected. It'll be better to clear the other options.

Breakpoints

There is no dialog for adding/editing breakpoints. You can use Debug -> Toggle Breakpoint, edit the Ignore, Condition and Script columns, or invoke Add Break / Add Watch [HRD], which brings up the command dialog.

Only points created with MI commands are kept in the list permanently.
Due to MI limitations:
- The catchpoints are displayed incompletely
- Disposition "dis" is ignored, and "del" is saved for breakpoints and tracepoints only
- The difference between software and hardware watchpoints is ignored, but gdb will create hardware watchpoints as needed.

For tracepoints, only the generic breakpoint commands and attributes are supported (with ignore for passcount), not the tracepoint-specific commands.

Apply on run is off by default for watchpoints, because they are often related to a local expression.

Shift-clicking Apply applies the breakpoint for the currently selected thread only.

GDB may report an error for invalid Condition and/or Script, but still accept them, and continue to emit errors each time they are evaluated.

The breakpoint line markers, View Source and double-click use the last known file name and line, as displayed in Location or expr. They may change when a breakpoint is applied or resolved.

With gdb 7.4 and later, the breakpoint list is updated by asynchronous gdb messages (except for async_break_bugs). Use Refresh to fully refresh it.

Condition, Script and watchpoint expr use the default 8-bit text mode.

For multi-address breakpoints, the individual locations are not loaded or saved, and are deleted as soon as the program is unloaded, so you may prefer to turn Auto run/exit off when using them. When a breakpoint is disabled, GDB treats all it's locations as disabled, despite their individual state. However, with at least enabled location for a file:line, the marker for enabled breakpoint will be used for that line.

Stack

The function arguments are subject to 8-bit text conversion. Their individual modes may be set via Locals.

Synchronize - select the current gdb frame. Shift-click: -stack-select-frame.

Show @entry - display any @entry arguments reported by gdb for the selected frame function. Depends on GDB "print entry-values". Applies to Locals too.

Locals

The first column is "1" for arguments, empty for local variables.

Watches

This is a flat list of expressions, evaluated each time the current thread stops or changes (subject to update_all_views), in the context of the current thread and frame. Unlike Inspect, any gdb-evaluatable expressions may be used, there is no need to apply them.

Locals/Watches

Modify is useful for setting individual array / structure elements.

Shift-clicking Modify displays strings as "TEXT" instead of 0xADDR, and characters as 'C' instead of VALUE (see Editing values).
Any char[] arrays will still be displayed as arrays.

Show .names - display member names. Shift+Click resets it to the value specified in Setup Program.

Memory

Group by is for visual convinience only and ignores endian.

Groups are not wrapped, so with Group by > 1, less than memory_line_bytes may be displayed.

A maximum of 16K may be displayed (128 lines * 128 bytes); gdb_buffer_length also limits the size.

Memory empty but Clear available means that the subpage can not be updated ATM; if you explicitly Clear it, no further updates will take place.

Debug Console

Redgdb stderr (or sometimes exec) error messages
Graynormal gdb messages
Cyancommands send to gdb
MagentaScope messages, mostly parsing errors

Typing a graphical ascii character or pressing Insert brings up the command dialog.

Note that whether the last displayed line is a gdb prompt is not a proper indicator if GDB is ready to receive commands. For example, in synchronous mode, GDB displays a prompt immediately resuming the program execution; or the prompt may be followed by asynchronous messages. The Scope state (Busy, Debug etc.) is more accurate.

Inspect Page

All -var-* commands except -var-update will be ignored when entered from the command line, because their output does not provide enough information to identify the variable object.

Jump To lists the top-level variables, which is useful if you have a lot of children displayed. It's disabled while gdb is inactive, because all variables are collapsed anyway.

Double-click or Return applies/unapplies a variable.

Add will try to apply the variable object immediately, Edit will not. Apply on run is off by default, because the variables are often local.

Expand is primary to change the expansion options. After a variable is applied, you can expand it simply by using the keyboard or mouse, like with any other gtk+ tree.

The command "echo ^(Scope)#07name" will try to expand the variable name. You can include such commands in your breakpoint scripts. The name must start will a letter ("-" will not do).

When modifying variables, gdb interprets "TEXT" as the identifier TEXT.

The format and 7-bit mode are saved only for the top-level variables, not for children (but see Keeping modes).

Preferences

Once again, trivial items are not included.

[scope]

gdb_buffer_length - the maximum length of a single gdb output message. Longer messages will be cut, and an "overflow" will be displayed in the debug console, possibly followed by a few other parsing errors. Default = 16383. Actual value is (the nearest larger power of 2) - 1, for example 16384 becomes 65535.

gdb_wait_death - hundreds of seconds to wait(3) gdb death on scope unload. Default = 20. When closing Geany, gdb will be destroyed by the operating system.

gdb_send_interval (win~1 only) - interval on which to retry sending commands to gdb if it's input buffer is full, in hundreds of seconds. Default = 5. The actual value may be larger, for example Scope may be activated only 10 times per second if Geany is idle.

async_break_bugs (win~1 only) - whether gdb escapes slashes twice in the asynchronous break messages. If true, only =breakpoint-deleted will be handled.

auto_view_source - seek in source on single click in threads, breakpoints and stack.

keep_exec_point - do not clear the execution point marker and Threads location columns when a thread execution is resumed.

visual_beep_length - hundreds of seconds to flash the state label on Scope errors. Default = 25.

debug_console_vte (*nix only) - use vte terminal for the debug console. The alternative is a GtkTextView based console, which has a few quirks, but consumes less CPU power. That can be useful if you use the console a lot, and have a slow CPU or a limited power supply. The win~1 version of Scope always uses GtkTextView.

sci_marker_first - Scope uses markers 17..19 by default; they may be changed to avoid conflicts with other plugins.

sci_caret_policy, sci_caret_slop - Scintilla Y caret policy when moving/scrolling to show the current execution point (does not affect the normal navigation and editing). Default policy = CARET_SLOP | CARET_JUMPS | CARET_EVEN, slop = 3.
See ScintillaDoc.html#SCI_SETYCARETPOLICY and Scintilla.h for more information.

unmark_current_line - disable the current line highlighting while debugging. Useful if the current line background covers the breakpoint or execution point backgrounds. Affects the source files only.

seek_with_navqueue - use Geany navqueue when seeking in source.

panel_tab_pos - see GtkPositionType. Some tab names will be shortened in Left and Right.

show_recent_items - number of items to display in Debug --> Recent Programs. Default = 10, maximum = 28. Note that Scope will always keep the settings for the last 28 programs; on project open/close and Geany startup, settings which are not visible in the menu may be loaded.

show_toolbar_items - bitmask: 1 = Run/Continue, 2 = Goto Cursor, 4 = Goto Source, 8 = Step Into, 16 = Step Over, 32 = Step Out, 64 = Terminate and 128 = Toggle Breakpoint.

tooltips_fail_action - 1 = blink on tooltip evaluate errors, 2 = display them as tooltips.

tooltips_send_delay - increase this setting to reduce the CPU time and GDB traffic used by the tooltips, or decrease it if they appear slower than your gtk+ setting.

pref_tooltips_length - maximum length of a tooltip message, 0 = unlimited. Default = 2048.

memory_line_bytes - maximum bytes per Memory line.

[terminal] (*nix only)

width, height - VTE widget (not terminal window) size

save_pos - auto save window position and widget size

padding - whether width and height include the extra VTE widget padding. If save_pos is active, they will be saved with the padding.

[disabled_break], [enabled_break], [execution_line]

mark - Scintilla mark. See Scintilla.h: SC_MARK_.

Notes

Changes in Geany VTE preferences will be applied when Scope is restarted.

Locale/UTF-8 conversion is fully supported for values only. Filenames not matching your locale and non-ascii identifiers are not guaranteed to work.

When editing a column while the program is running, it's value will be updated after/if the respective gdb command is executed.

If you use multiply Geany instances with session management, make sure that only one of them has Scope enabled. Otherwise, the list of programs and their settings may break.

A disabled check button or check menu item means that the respective functionality is unavailable; it doesn't matter if the interface element is checked or not.

All subpages will be updated faster if you keep them unsorted.

Editing values

GDB often displays values in format unsuitable for assigning. So when editing a value, Scope will try to:
- Cut any member names, because set foo = { i = 4, c = 'x' } actually means i = 4; c = 'x'; foo = {4, 'x'}
- Cut any array indexes
- Cut 0xADDR "TEXT" to 0xADDR. Leaving both is invalid, and "TEXT" always creates a new string pointer
- Cut VAL 'C' to VAL. Again, leaving both is invalid
- Detect <repeats, <optimized etc. and clear the entire value if editing via the Value column
- Convert char[] arrays displayed as string to character array, because a string always includes a trailing '\0', so a char[4] may be displayed as "TEXT", but can not be assigned like that.
  Note that UTF-8 texts will be converted to 8-bit character arrays.

Of course, you can still enter a "TEXT" or a 'C'haracter.

The above steps are not guaranteed to work; in particular, single-quoted strings ending with backslash will fail. If parsing errors are detected when editing the Value column, the entire value will be cleared - but that is not guaranteed to work either.

Keeping modes

The 7-bit, .names etc. modes for temporary objects, such as local variables, are not saved. However, there is a global list with names and modes, and when you change a mode, it's saved in that list. Then, when a temporary object is created, Scope searches the list, and sets the modes (if any) for that object. For inspect children, the displayed names are used (including numbers for array elements), not the fully qualified names.

Sample dark colors

[disabled_break]
mark=0
alpha=256
fore=#008000
back=#005000

[enabled_break]
mark=0
alpha=256
fore=#0000E0
back=#000068

[execution_line]
mark=4
alpha=256
fore=#F0F000
back=#707000

Pre-FAQ

Questions which are likely to be asked frequently:

Q. How about tree lists in Locals and Watches?

A. They operate with the entire struct/array values, so creating tree lists would be completely artificial. Some front ends automatically create/delete gdb variables for the locals as they come into/go out of scope, or even or each step, but I'm not willing to do that. The watches can not be represented with variables (see Watches). So, use Inspect for tree lists.

Why isn't Interrupt implemented as -exec-interrupt?

Because it requires a gdb prompt, and see Bugs. Of course, using target-specific functions has it's own drawbacks, but you can always try to send an -exec-interrupt from the GDB command line if you need it.

Q. Why not leave the member names (array indexes) while editing a value?

A. They must be removed before sending the value to GDB. Leaving them while editing gives the false impression that you can assign selectively, while in fact omitting a "foo = value, " moves all values left by 1, and changing a name or index has no effect.

Q. A "signal `project-before-save' is invalid" warning is displayed on Geany startup, and an "assertion `handler_id > 0' failed" message on quit.

A. Your Geany does not support this signal. Either apply the patch from Geany sourceforge patch tracker ID 3594050 and recompile it, or make sure to Terminate the debugged program before quitting Geany or switching to another project. Otherwise, your source files will be marked as read-only when the current project is reopened. Of course, you can awlays unlock them manually (via Document --> Read Only), so it's nothing serious.

Bugs

For some reason, -exec-interrupt under Linux (*nix?) signals gdb and Geany, but not the program/thread. The other Geany debugger plugin has the same problem.

Report bugs to <dimitar.zhekov@gmail.com>

TODO

See TODO.

Not TODO

"The master programmer knows when to leave things in their simple form."
-- Eloquent Javascript
Things that will not be implemented in Scope:

Legal information

License

Scope is distributed under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

Copyright

Scope 0.84, Copyright (C) 2013 Dimitar Toshkov Zhekov

The menu and toolbar icons are from Netbeans, except for BreakPoint.

The End