README.md
author Jan Vrany <jan.vrany@labware.com>
Fri, 08 Sep 2023 12:40:22 +0100
changeset 317 7f63737e0374
parent 308 2f4c59d35518
permissions -rw-r--r--
Fix `GDBMIDebugger` after rename of `GDBStXUnixProcess` to `GDBUnixProcess` ...in commit d1422e1ee.

# libgdbs

*libgdbs* is a library providing smalltalk interface for GDB.

## Features

 * event-based interface
 * convenient API to inspect and query current state of a debugee
 * support for custom disassemblers allowing for custom code analysis (not part
   of *libgdbs*)

## Example Use

```
| b0 thread frame i r |

"Create new debugger object - `gdb`."
gdb := GDBDebugger new.

"Load an executable to debug, the parameter is a String
 with path to the executable."
gdb executable: GDBDebuggeesResource current binaryFactorial1.

"Set breakpoint on function `factorial(int)`, see`factorial.c`(*).
 Here we use `GDBDebugger >> #send:` to send a standard CLI command
 to `gdb`. The method blocks and returns once the command is executed.
 See class `GDBDebugger`, protocol 'commands' for more ways to send a
 command to GDB.

 (*) https://jan.vrany.io/hg/jv-libgdbs/file/tip/tests/c/factorial1.c
"
gdb send: 'b factorial'.

"You may ask `gdb` for list of breakpoints, ..."
gdb breakpoints.

"...retrieve a breakpoint as an object..."
b0 := gdb breakpoints first.

"...and then use breakpoint object to get details
 for example on what file and line the breakpoint was
 put:"
'location is %1 : %2' bindWith: b0 file with: b0 line.

"Breakpoint objects can also be used to manipulate it,
 for example to set a condition when the breakpoint should
 hit. See class `GDBBreakpoint`. "
b0 condition: 'i == 1'.

"Now let's run debuggee util it hits the breakpoint using
 GDB's `r` (or `run`) command. Here we (have to) use a different
 API than plain `#send: - `#send:` executes the command and return
 as soon as the command is executed. This is not what we want now,
 here we want to run the debuggee and wait until breakpoint hits
 (or until some error occur). In theory, this could be hours after
 the `r` command is executed.

 For cases like this, libgdb's provides another API:
 `GDBDebugger >> send:andWaitFor:` to wait for 'stopped' event:"
gdb send: 'r' andWaitFor: GDBStoppedEvent.

"Now let's see where we have stopped. Since GDB allows
 to debug multiple processes (called inferiors in GDB parlance)
 and each process may have multiple threads, we have to first get
 a the thread and then ask the thread for first (newest) frame of
 threads callstack. In this case, there' only one process with
 only one thread, so getting the thread is easy.

 Note, that there's always a callstack with at least one frame."
thread := gdb selectedInferior threads first.
frame := thread stack first.

"Again, thread and frame are objects and can be used to access
 program state"
frame func.    " -> 'factorial'"
i := frame variables first.
i name.        " -> 'i' "
i value.       " -> '1' "

r := frame registers first.
r name.        " -> 'rax' (depending on target architecture, of course) "
r value.

"Finally, remove all breakpoints and let the program continue and finish..."
gdb send: 'del'.
gdb send: 'c' andWaitFor: GDBThreadGroupExitedEvent.
```

For more examples, load `jv:libgdbs/tests` and see `GDBDebuggerExamples`. You may also
want to have a look at tests `GDBDebuggerTestsR`.

## How to load

### ...into Smalltalk/X on Linux

1.  Create a directory where to download and install all components - in following
	steps we use `/where/you/want/it` but naturally, choice is yours:

        mkdir -p /where/you/want/it
        cd /where/you/want/it

2.  Get suitable GDB. Stock GDB 13 and later should be fine.

    Alternatively, you may want to build suitable GDB from sources, see
    [doc/GDB.md][9] for details.

3.  Get [Smalltalk/X jv-branch][3]. Pre-build "toy" binaries for Linux
    can be found at [https://jan.vrany.io/download/smalltalkx/devel][5]:

        wget https://dl.vrany.io/public/smalltalkx/devel//YYYY-MM-DD_NNN/smalltalkx-jv-branch-8.0.99_buildNNN_x86_64-pc-linux-gnu.tar.bz2
        tar xf smalltalkx-jv-branch-8.0.99_buildNNN_x86_64-pc-linux-gnu.tar.bz2
        rm smalltalkx-jv-branch-8.0.99_buildNNN_x86_64-pc-linux-gnu.tar.bz2

    Alternatively, you may want to build Smalltalk/X from sources, see
    [build instructions][12]. This is actually preferred way to work with
    Smalltalk/X.

4.  Get *jv:libgdbs*:

        mkdir -p jv
        hg clone https://jan.vrany.io/hg/jv-libgdbs jv/libgdbs

5.  Start Smalltalk/X:

        ./smalltalkx-jv-branch-8.0.99_buildNNN_x86_64-pc-linux-gnu/bin/stx --package-path /where/you/want/it

    Please note, that `/where/you/want/it` should be the path to where you
    created `jv` directory in which libgdbs has been cloned in step 3.

6.  In Smalltalk/X workspace, load `jv:libgdbs` and set path to suitable GDB:

		Smalltalk loadPackage: 'jv:libgdbs'.
        UserPreferences current gdbCommand: '/where/you/want/it/gdb_x86_64-pc-linux-gnu_YYYY-MM-DD_XXXXXXXX_NN/bin/gdb'.

7.  Now you may create an instance of GDB to play with - in Smalltalk/X
    workspace execute:

        gdb := GDBDebugger new.

### ...into Smalltalk/X on Linux

For installing on Windows, see [doc/GettingStartedOnWindows.md][13]

### ...into Pharo on Linux

*WARNING* Pharo port of LibGDBs is still work in progress and there are few
known (and many unknown) loose ends.

1.  Create a directory where to download and install all components - in following
    steps we use `/where/you/want/it` but naturally, choice is yours:

        mkdir -p /where/you/want/it
        cd /where/you/want/it

2.  Get suitable GDB. Stock GDB 13 and later should be fine.

    Alternatively, you may want to build suitable GDB from sources, see
    [doc/GDB.md][9] for details.

4.  Get *jv:libgdbs*:

        mkdir -p jv
        hg clone https://jan.vrany.io/hg/jv-libgdbs jv/libgdbs

5.  Go to `jv/libgdbs/ports/pharo` and type `make source`.

    If you just want to have a quick look, type `make run` - this will
    run Pharo 8 image with LibGDBs loaded.

    If you want to load LibGDBs into your image, just evaluate:

    ```
    Metacello new
        baseline: 'LibGDBs';
        repository: 'tonel:////where/you/want/it/jv/libgdbs/ports/pharo/src-generated';
        load.
    ```

## Documentation

Some documentation can be found in [doc][10] directory, see [doc/README.md][10]

## Reporting issues

Use [Smalltalk/X jv-branch issue tracker][6] to [report issues][7] (you may need
to login using your Google account in order to submit an issue). Alternatively,
send a message to [Smalltalk/X mailing list][8].

## Author

Jan Vrany `<jan [at] vrany [.] io>`

## License

This software is licensed under *MIT license*.
You may find a full license text in `LICENSE.txt`.

[2]: https://www.gnu.org/software/gdb/
[3]: https://jan.vrany.io/stx
[4]: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git
[5]: https://dl.vrany.io/public/smalltalkx/devel
[6]: https://jan.vrany.io/stx/report/9
[7]: https://jan.vrany.io/stx/newticket
[8]: https://groups.google.com/forum/#!forum/stx-jv
[9]: doc/GDB.md
[10]: doc/README.md
[11]: https://jan.vrany.io/public/gdb
[12]: https://jan.vrany.io/stx/wiki/Documentation/BuildingStXWithRakefiles
[13]: doc/GettingStartedOnWindows.md