Giter VIP home page Giter VIP logo

gep's Introduction

GEP (GDB Enhanced Prompt)

demo.mov

GEP (GDB Enhanced Prompt) is a GDB plug-in which make your GDB command prompt more convenient and flexibility.

Why I need this plug-in?

GDB's original prompt is using hardcoded built-in GNU readline library, we can't add our custom function and key binding easily. The old way to implement them is by patching the GDB's C source code and compiling it again.

But now, you can write your function in Python and use arbitrary key binding easily with GEP without any patching!

And also, GEP has some awesome features already, you can directly use it!

Features

  • Ctrl+r for fzf history reverse search
  • ↑ key for partial string matching in history
  • TAB for auto-completion with:
    • fzf (When fzf is installed)
    • floating window (Similar to IPython's auto-completion)
  • fish-like autosuggestions (β†’ key to accept the suggestion)
  • has the ability to build custom key binding and its callback function by modifying geprc.py
  • compatible with the latest version of your favorite GDB plug-ins:

How to install it?

Make sure you have GDB 8.0+ (ideally GDB 14.1+ for the best experience) and compiled with Python3.8+ bindings, then:

  1. Install git
  2. Make sure you have virtualenv installed
  3. Install fzf: Installation (Optional, but GEP works better with fzf)
  4. Install this plug-in by:
# You could also choose other directories to install GEP if you want
git clone --depth 1 https://github.com/lebr0nli/GEP.git ~/.local/share/GEP
~/.local/share/GEP/install.sh
  1. Enjoy!

Important

After the installation, the script will automatically add source /path/to/GEP/gdbinit-gep.py to your ~/.gdbinit file. Please make sure this line is always at the end of your ~/.gdbinit file during future modifications of your ~/.gdbinit to avoid some unexpected behaviors.

How to update the version of GEP?

If your ~/.gdbinit is something like this: source ~/.local/share/GEP/gdbinit-gep.py, then you can update GEP by:

cd ~/.local/share/GEP && git pull && ./install.sh

For more configuration

You can modify the configuration for history, auto-completion, and other GEP configurations in /path/to/GEP/gdbinit-gep.

You can also add your custom key bindings by modifying /path/to/GEP/geprc.py.

Note

The example subdirectory houses samples and default configurations.

The trade-offs

Since GDB doesn't have a good Python API to fully control and emulate its prompt, this plug-in has some side effects.

However, the side effects are avoidable, here are the guides to avoid them:

TUI mode

Somehow, GEP breaks the TUI mode in GDB, so it's advisable not to use GDB's built-in TUI when working with GEP (refer to issue #13).

Instead of using gdb TUI, I personally recommend trying pwndbg/pwndbg, hugsy/gef and cyrus-and/gdb-dashboard to enhance your debugging experience.

If you have any ideas to resolve this issue, PRs are greatly appreciated. πŸ™

gdb.event.before_prompt

The GDB Python API event: gdb.event.before_prompt may be called only once.

So if you are using a GDB plug-in that is listening on this event, this plug-in will cause some bugs.

Note

pwndbg, gef, and gdb-dashboard won't be affected by this side effect so far, but please open an issue if you find any plug-in that is affected by this side effect.

To avoid this, you can change the callback function by adding them to gdb.prompt_hook, gdb.prompt_hook has almost the same effects with event.before_prompt, but gdb.prompt_hook can be directed invoke, so this plug-in still can emulate that callback for you!

dont-repeat

When your input is empty and directly press ENTER, GDB will execute the previous command from history if that command doesn't have the property: dont-repeat.

As far as I know, there is no GDB API for checking a command's property.

So, I added some commonly used commands (for original GDB API and GEF) which have that property in a set to avoid repeatedly executing them.

If you have some user-defined function that has dont-repeat property, add your command into the set manually, too.

Note

The set of those user-defined commands are in geprc.py and the variable name for it is DONT_REPEAT.

If you found some builtin commands which should or shouldn't be added by default, let me know on the issue page, thanks!

Uninstall

If this is your current ~/.gdbinit file after the installation:

source /path/to/GEP/gdbinit-gep.py

Then, you can uninstall this plug-in by:

rm -rf /path/to/GEP

And remove source /path/to/GEP/gdbinit-gep.py from your ~/.gdbinit.

Credits

Some ideas/code are inspired by hugsy/gef and pwndbg/pwndbg.

Thanks!

Bugs, suggestions, and ideas

If you found any bug, or you have any suggestions/ideas about this plug-in, feel free to leave your feedback on the GitHub issue page or send me a pull request!

Thanks!

gep's People

Contributors

lebr0nli avatar qiuwei avatar sweetbbak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

gep's Issues

Error in `gdb.prompt_hook` might cause infinite loop

If we set gdb.prompt_hook as following:

x = 0


def foo(current_prompt):
    global x
    if x & 1:
        x += 1
        raise gdb.error("err")
    x += 1
    return "(test) "


gdb.prompt_hook = foo

GEP will step into an infinite loop after the first prompt.

Update the demo on `README.md`

[![asciicast](https://asciinema.org/a/TJiEkHv3cqieR0XizG41uOg93.svg)](https://asciinema.org/a/TJiEkHv3cqieR0XizG41uOg93)

The demo on README.md is a little bit outdated, we need an update for it.

Add type hints

I was too lazy to add type hints, so the code ended up looking messy.
We might have to consider incorporating mypy into our lint.sh script down the line and adding the missing type hints.

gdb doesn't import prompt_toolkit from $HOME/GEP/

This is a really cool plugin and I'm eager to use its features. However, when I try to load it with source ~/GEP/.gdbinit-gep.py, I get an error about "'_GdbOutputFile' object has no attribute 'fileno'". It looks like there's some issue with prompt_toolkit. To get a full backtrace, I did the following:

(gdb) python
>from prompt_toolkit import PromptSession
>p = PromptSession()
>end
Traceback (most recent call last):
  File "<string>", line 2, in <module>
  File "/home/dp12/.local/lib/python3.8/site-packages/prompt_toolkit/shortcuts/prompt.py", line 468, in __init__
    self.app = self._create_application(editing_mode, erase_when_done)
  File "/home/dp12/.local/lib/python3.8/site-packages/prompt_toolkit/shortcuts/prompt.py", line 719, in _create_application
    application: Application[_T] = Application(
  File "/home/dp12/.local/lib/python3.8/site-packages/prompt_toolkit/application/application.py", line 277, in __init__
    self.output = output or session.output
  File "/home/dp12/.local/lib/python3.8/site-packages/prompt_toolkit/application/current.py", line 70, in output
    self._output = create_output()
  File "/home/dp12/.local/lib/python3.8/site-packages/prompt_toolkit/output/defaults.py", line 77, in create_output
    return Vt100_Output.from_pty(
  File "/home/dp12/.local/lib/python3.8/site-packages/prompt_toolkit/output/vt100.py", line 466, in from_pty
    fd = stdout.fileno()
AttributeError: '_GdbOutputFile' object has no attribute 'fileno'
Error while executing Python code.

Any ideas about what might be happening?

pwndbg's venv issue

In the latest pwndbg, it used venv to load its dependencies and removed all site-packages's import path.
This causes GEP to fail to load the dependency: prompt_toolkit.
To fix this, we need to create venv for GEP as well or somehow install prompt_toolkit into pwndbg's venv.
I think creating venv probably it's a better idea.

fzf completion is incorrect when I set breakpoint at runtime

Hello,

First, thanks for making this simple yet awesome tool! :D

Here's the bug description:

When I set breakpoint after I run the program, the fzf tab auto-completion for symbol name encounters weird behavior.

For example, if I type B then press <tab>, the first character of each symbol name is overwritten as B.

See the following screenshot. The function name foo::B::func() is displayed as Boo::B::func(). Thus, if I press enter for completion, it will fill the name as Boo::B::func().

It seems that GEP has some problem with searching non-prefix string.

image

Here's the source.cpp:

#include <iostream>
using namespace std;

namespace foo {
class B {
  public:
    void func()
    {
        cout << "B:func" << endl;
    }
};
}
int main()
{
    foo::B b;
    b.func();
    return 0;
}

Here's my system info:

Ubuntu 20.04 (WSL 1) with all packages installed from APT
g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
Python 3.8.10

Please note that the above example is very simple. I don't if this problem occurs BEFORE I run the program.

Add unit tests

We should find a way to test the features of GEP.


#39 was merged, but there are still many TODOs:

  • Add tests for tab auto-completion.
  • Run tests only when necessary (currently, tests run even if README.md is modified). (Resolved with #43)
  • Update the Dockerfile to rebuild the image only when needed.
  • Run tests on different platforms (currently, tests are only done on Ubuntu 22.04).

Error when starting gdb

When I installed as instructed in README,

$ bash -c "$(curl -fsSL https://raw.githubusercontent.com/lebr0nli/GEP/main/install.sh)"

I've got this error when starting GDB.

File "~/GEP/.gdbinit-gep.py", line 77
    fzf_cmd = [f"awk '!seen[$0]++' {shlex.quote(HISTORY_FILENAME)}"]
                                                                  ^
SyntaxError: invalid syntax

Smarter tab completion for breakpoints

Vanilla GDB's autocompletion can't complete breakpoint numbers when the buffer contains commands like disable<SPACE> or enable<SPACE>.
It would be nice if we could complete the breakpoint numbers and preview the breakpoint info with fzf when hitting the tab key.

multi-line command hangs GDB

When you input a multi-line GDB command (e.g. while), GEP hangs and CPU usage increases to 100%.

image

In normal GDB, the result should be:
image

It may not be a serious problem since I don't use multi-line commands very often. But it indeed hangs and crashes GDB.

Consider using GDB MI commands

gdb.execute_mi is added after GDB 14.1

GDB MI -complete command somehow can provide better competitions then normal complete command:

>>> gdb.execute_mi("-complete","enable ")
{'completion': 'enable ', 'matches': ['enable breakpoints', 'enable count', 'enable delete', 'enable display', 'enable frame-filter', 'enable mem', 'enable once', 'enable pretty-printer', 'enable probes', 'enable type-printer', 'enable unwinder', 'enable xmethod'], 'max_completions_reached': '0'}
>>> gdb.execute("complete enable ")
enable

Problem with completion popup text

I was trying out this plugin (really cool btw) and I think there is a problem with the completion:

For example:

GEP

The rho)) prefix is off.

somthing was wrong with layout src

Hi, thank you for the convenience brought by this tool to my debugging experience. It is really useful!
I find something was wrong when gdb run "layout [src|asm|}regs|split|next|prev]". The specific problems are described below.

When I typed "n", the pane of src was broken, and gdb exited when I continue typing "n", the following is the screenshot
image

The Operator system is Ubuntu 20.04.6 TLS
The version of gdb is 9.2

thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.