How to develop GDBFrontend plugins
GDBFrontend supports plugins. Plugin development includes a few simple steps. You can develop plugins easily with following the instructions.
Example Plugin
There is an example plugin (hello) in plugins/hello.
Enable it before start the tutorial: Go to config.py and comment the line "hello":
disabled_plugins = [
"hello"
]
Plugin FS Structure
GDBFrontend plugins are stored in plugins/ directory in the GDBFrontend root.
A typical plugin files look like this:
plugins/
hello/
frontend/
html/
hello.html
js/
hello.js
css/
hello.css
url_modules/
api.py
config.py
urls.py
hello.py
Plugin Name Format
- On File System:
hello(hello/directory,hello.py) - Plugin Backend Class:
HelloPlugin
Enabling/Disabling a Plugin
You can disable a plugin with adding plugin name to config.disabled_plugins.
Plugin Load Order
You can specify plugin load order with config.plugin_order. Plugins from config.plugin_order will be loaded in order, after that the rest will be loaded.
Plugin Files
config.py
Includes basic information about your plugin.
DESCRIPTION = "Example GDBFrontend plugin."
AUTHOR = "Oğuzhan Eroğlu <rohanrhu2@gmail.com> (https://oguzhaneroglu.com/)"
HOMEPAGE = "https://github.com/rohanrhu/gdb-frontend"
VERSION = [0, 0, 1]
hello.py
Plugin backend file must be named as [plugin name].py and plugin class must be named as [plugin name]Plugin and intherits plugin.GDBFrontendPlugin.
import importlib
import plugin
gdb = importlib.import_module("gdb")
class HelloPlugin(plugin.GDBFrontendPlugin):
def __init__(self):
plugin.GDBFrontendPlugin.__init__(self)
def loaded(self):
gdb.events.new_objfile.connect(self.gdb_on_new_objfile)
def unloaded(self):
gdb.events.new_objfile.disconnect(self.gdb_on_new_objfile)
def gdb_on_new_objfile(self, event):
print("[HELLO] Event: new_objfile:", event)
urls.py
Includes URL definitions for GDBFrontend REST API. Plugins can define URLs and use them for communicating with each other.
URLs must be defined in a python dict named as urls in the following format:
urls = {
"example-api": {
"url": "/hello/api",
"match": "^/hello/api",
"module": "plugins.hello.url_modules.api"
}
}
Rest API Modules
Rest API Module URLs must be defined in plugin.urls. Module files are stored in url_modules/ directory.
Plugin URL modules can be accessed with the path like plugins.hello.url_modules.[module name] and you must use it for plugin.urls["[plugin name]"]["module"].
A URL module file includes a function named as run(request, params) and GDBFrontend calls that on HTTP request. A typical URL module like this:
import json
import urllib
import api.debug
def run(request, params):
if params is None: params = {}
url_path = urllib.parse.urlparse(request.path)
qs_params = urllib.parse.parse_qs(url_path.query)
result_json = {}
result_json["ok"] = True
result_json["sources"] = api.debug.getSources()
request.send_response(200)
request.send_header("Content-Type", "application/json; charset=utf-8")
request.end_headers()
request.wfile.write(json.dumps(result_json).encode())
Plugin Objects
Plugin objects are exists in plugin.plugins dict as plugin.plugins["[plugin name]"] = plugin and plugin is an instance of your plugin class that inherits GDBFrontendPlugin.
Plugin Object Attributes
plugin.moduleplugin.nameplugin.is_loadedplugin.locationplugin.configplugin.urls
Frontend
Frontend files are stored in the plugins/[plugin name]/frontend/ directory. There are three basic directory:
frontend/
css/
[plugin name].css
html/
[plugin name].html
js/
[plugin name].js
html/[plugin_name].html will be included to DOM as default.
* css/[plugin_name].css will be included as default.
* js/[plugin_name].js will be included as default.
Plugin's frontend/ directory is also served over HTTP and its content will be accessable with a URL like /plugins/[plugin_name]/html/foo.html or /plugins/[plugin_name]/js/bar.js.
GDBFrontend Namespace
All GDBFrontend stuff are exists in GDBFrontend object in Javascript. An example, you can access version like GDBFrontend.version.
Backend Configuration
You can access backend configuration via GDBFrontend.config.
Frontend Components
Root Components
All root components are stored in GDBFrontend.components.
Sub Components
Sub components are stored in component.components.
Component: gdbFrontend
GDBFrontend is the main component at root and it uses another components as sub component. It is accesable with GDBFrontend.components.gdbFrontend.
Sub components of gdbFrontend are accessable via GDBFrontend.components.gdbFrontend.components.
For an example you can get open file tabs like this:
> GDBFrontend.components.gdbFrontend.components.fileTabs.files
< (3) [{…}, {…}, {…}]
or getting breakpoints from BreakpointsEditor component instance from GDBFrontend component instance.
> GDBFrontend.components.gdbFrontend.components.breakpointsEditor.breakpoints
< [{…}, {…}]
Let's switch to first file tab:
var switchTo = GDBFrontend.components.gdbFrontend.components.fileTabs.files[0];
GDBFrontend.components.gdbFrontend.components.fileTabs.switchFile({file: switchTo});