Scope

A relatively 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.25 or later and the respective libraries.

GDB 7.3 or later.

*nix only: VTE library.

Windows only: 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 on load 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 will 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 tab text will become 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 varname=value per line.

Load script is a gdb script, executed when gdb is loaded. May be used to setup the program. If no Executable is specified, Scope will assume that the script, if any, loads the program.

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. 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 on load at - set a temporary breakpoint when the program is loaded. If you leave the text field empty, Scope will try to find the 1st line of code and place a breakpoint on it. Any breakpoint options and location are allowed in the text, for example main for C/C++ programs. Since setting a breakpoint requires a program, this option 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 for confirmation.

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 Windows.

Run/Continue [NHD]

Not debugging state (first run):
- Load and setup gdb
- Load the Executable and execute the Load script, if any
- If an executable and/or a load script was processed, and there were no errors so far:
• apply any points and inspects marked as Apply on Run and create the Temporary breakpoint on load
• run the program if Auto run/exit is checked, at least 1 breakpoint was applied, and there weren't any errors.

On errors, Scope will enter Hang state, letting you execute commands manually, and fix or recreate any points or inspects if needed.

Hang state: try to apply any unapplied points or inspects marked as Apply on Run, and -exec-run despite any errors.

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: terminate gdb, even if Auto Run/exit is unchecked.
If you want to terminate the program without unloading gdb, switch to Threads and invoke Terminate or Send Signal.

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

Otherwise: -gdb-exit.

GDB Command [^N]

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

Both MI and CLI commands are supported.

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

Synchronize 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 (*nix only)

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.

Breakpoints created with MI commands are kept in the list permanently. When a temporary MI breakpoint is hit, it's Id column is cleared. Toggle breakpoint, Add Break and Add Watch use MI commands.

Breakpoints created with CLI commands (from scripts or GDB Command) are removed when the program is unloaded. When a temporary CLI breakpoint is hit, it's removed. If a MI command produces none or invalid output, and the breapoint appears later (from Refresh or async message), Scope will consider it CLI.

Scope remembers the total (initial) ignore count, and re-applies it on each run. When a breakpoint is applied, Ignore shows the current value, followed by the total value surrounded in brackets. On gdb 'ignore' (or -break-after followed by refresh), the total value will be set only if the new count is larger: there is no way to tell whether a smaller count resulted from a command execution or breakpoint hit(s). Edit the Ignore column to set a smaller count.

The above paragraphs apply to watchpoints and tracepoints as well.

Due to MI limitations and deficiencies:
- The catchpoints are displayed incompletely and removed on program unload
- Disposition "dis" is ignored, and "del" (i.e. temporary) is saved for break and trace points 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, if any.

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 one 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, and 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).

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.

Windows console

Displayed automatically by Windows when starting a Windows console program, and closed automatically when the program terminates. To leave the console open on program termination, set breakpoints at ExitProcess / TerminateProcess.

Side pages

Inspect

-var-* commands entered from the command line will not update the Inspect view, because their output does not provide enough information to identify the variable object, and/or their PRINT-VALUES argument is unknown.

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 apply 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).

Registers

Scope will query the register names once after a program is loaded, or when the gdb executable is changed. If you switch to a different architecture, but your gdb name remains the same, invoke Query from the local menu.

Preferences

Once again, trivial items are not included.

[scope]

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

var_update_bug - whether -var-update causes internal gdb error if the program is loaded but not running. If true (the default), the update of inspect expressions (including Refresh) will be disabled in Hand state. AFAIK, they will always have the globally initialized values (if any) in that state anyway.

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 the entire 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.

Frame-dependent commands entered from the command line will not update the respective view, because their output does not contain thread and frame information.

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 is 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.

Shared memory

Scope does not know which Inspect/Watch expressions are thread and frame dependent, as well as whether the Memory address and range are process/thread dependent, so their handling is a compromise.
In particular:
- the values will not be updated if threads exist, but none is selected, or if the selected thread is running
- for Watches and Inspect, Scope will try to select a frame before sending the update command(s)
- on a thread or frame change, if the values can not be updated at the moment, they will not be cleared.

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

Various tests, source code checks etc.
Format (natural, decimal...) for Watches?
Add clear icon to entries? not very useful.
Don't remove [index] along with member names?
libtool support / exec wrapper support.

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.94, Copyright (C) 2015 Dimitar Toshkov Zhekov

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

The End