mirror of
https://github.com/cs01/gdbgui
synced 2024-11-16 07:47:46 +01:00
add manifest file; cleanup dependencies
This commit is contained in:
parent
5dbc937447
commit
2b2cba4351
5 changed files with 57 additions and 49 deletions
18
README.md
18
README.md
|
@ -1,24 +1,34 @@
|
|||
|
||||
[![Build Status](https://travis-ci.org/cs01/gdbgui.svg?branch=master)](https://travis-ci.org/cs01/gdbgui)
|
||||
|
||||
Still under active development, with a changing codebase/api.
|
||||
|
||||
# A browser-based gui for GDB
|
||||
The goal of this project is to reduce the learning curve of GDB to zero, including autocompletion and documentation of all commands.
|
||||
|
||||
Made with a lightweight Python server (Flask), and JavaScript for the frontend. Simply run the server, then view the page. Tested on Ubuntu 16.04 with Chrome.
|
||||
|
||||
## Installation and Use
|
||||
|
||||
Either
|
||||
|
||||
pip install gdbgui
|
||||
|
||||
Or
|
||||
|
||||
git clone https://github.com/cs01/gdbgui
|
||||
pip install -r gdbgui/requirements.txt
|
||||
gdbgui/gdbgui/backend.py
|
||||
|
||||
|
||||
Then
|
||||
|
||||
python -m gdbgui.backend
|
||||
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
|
||||
|
||||
Then open `http://127.0.0.1:5000/` in a browser and enjoy!
|
||||
|
||||
A pip install package will be released when codebase is more stable
|
||||
|
||||
## Compatibility
|
||||
Tested on Python versions
|
||||
|
||||
* 2.7
|
||||
* 3.3
|
||||
* 3.4
|
||||
|
|
2
gdbgui/MANIFEST.in
Normal file
2
gdbgui/MANIFEST.in
Normal file
|
@ -0,0 +1,2 @@
|
|||
recursive-include static
|
||||
recursive-include templates
|
|
@ -1,15 +1,18 @@
|
|||
#!/usr/bin/env python
|
||||
from flask import Flask, render_template, jsonify, session
|
||||
from flask import Flask, render_template, jsonify
|
||||
import os
|
||||
import argparse
|
||||
from flask import request
|
||||
import signal
|
||||
from ipdb import set_trace as db
|
||||
from pygdbmi.gdbcontroller import GdbController
|
||||
import webbrowser
|
||||
|
||||
|
||||
BASE_PATH = os.path.dirname(os.path.realpath(__file__))
|
||||
TEMPLATE_DIR = os.path.join(BASE_PATH, 'templates')
|
||||
STATIC_DIR = os.path.join(BASE_PATH, 'static')
|
||||
DEFAULT_HOST = '0.0.0.0'
|
||||
DEFAULT_PORT = 5000
|
||||
|
||||
|
||||
app = Flask(__name__, template_folder=TEMPLATE_DIR, static_folder=STATIC_DIR)
|
||||
|
@ -17,6 +20,7 @@ app.jinja_env.add_extension('pyjade.ext.jinja.PyJadeExtension')
|
|||
|
||||
gdb = None
|
||||
|
||||
|
||||
def server_error(obj):
|
||||
return jsonify(obj), 500
|
||||
|
||||
|
@ -26,24 +30,24 @@ def client_error(obj):
|
|||
|
||||
|
||||
def get_extra_files():
|
||||
extra_dirs = ['.']
|
||||
extra_files = extra_dirs[:]
|
||||
for extra_dir in extra_dirs:
|
||||
for dirname, dirs, files in os.walk(extra_dir):
|
||||
for filename in files:
|
||||
filename = os.path.join(dirname, filename)
|
||||
if os.path.isfile(filename):
|
||||
extra_files.append(filename)
|
||||
extra_files = []
|
||||
for dirname, dirs, files in os.walk(TEMPLATE_DIR):
|
||||
for filename in files:
|
||||
filename = os.path.join(dirname, filename)
|
||||
if os.path.isfile(filename):
|
||||
extra_files.append(filename)
|
||||
return extra_files
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def gdbgui():
|
||||
"""Render the main gdbgui interface"""
|
||||
return render_template('gdbgui.jade')
|
||||
|
||||
|
||||
@app.route('/run_gdb_command', methods=['POST'])
|
||||
def run_gdb_command():
|
||||
"""Run a gdb command"""
|
||||
if gdb is not None:
|
||||
try:
|
||||
cmd = request.form.get('cmd') or request.form.getlist('cmd[]')
|
||||
|
@ -54,8 +58,10 @@ def run_gdb_command():
|
|||
else:
|
||||
return client_error({'message': 'gdb is not running'})
|
||||
|
||||
|
||||
@app.route('/get_gdb_response')
|
||||
def get_gdb_response():
|
||||
"""Return output from gdb.get_gdb_response"""
|
||||
if gdb is not None:
|
||||
try:
|
||||
response = gdb.get_gdb_response()
|
||||
|
@ -68,7 +74,7 @@ def get_gdb_response():
|
|||
|
||||
@app.route('/read_file')
|
||||
def read_file():
|
||||
"""Used to get contents of source files that are being debugged"""
|
||||
"""Read a file and return its contents as an array"""
|
||||
path = request.args.get('path')
|
||||
if path and os.path.isfile(path):
|
||||
try:
|
||||
|
@ -83,8 +89,8 @@ def read_file():
|
|||
|
||||
|
||||
def signal_handler(signal, frame):
|
||||
"""handle ctrl+c (SIGINT) and make sure the child process is killed!"""
|
||||
global gdb
|
||||
"""handle ctrl+c (SIGINT) to make sure the child gdb process is killed"""
|
||||
print("Received signal %s. Shutting down gdbgui." % signal)
|
||||
if gdb is not None:
|
||||
try:
|
||||
gdb.exit()
|
||||
|
@ -96,6 +102,7 @@ def signal_handler(signal, frame):
|
|||
|
||||
|
||||
def quit_backend():
|
||||
"""Shutdown the flask server. Used when programmitcally testing gdbgui"""
|
||||
gdb.exit()
|
||||
func = request.environ.get('werkzeug.server.shutdown')
|
||||
if func is None:
|
||||
|
@ -103,31 +110,39 @@ def quit_backend():
|
|||
func()
|
||||
|
||||
|
||||
def setup_backend(serve=True, port=5000, debug=False):
|
||||
def open_browser(host, port):
|
||||
if host.startswith('http'):
|
||||
url = '%s:%s' % (host, port)
|
||||
else:
|
||||
url = 'http://%s:%s' % (host, port)
|
||||
print(" * Opening gdbgui in browser (%s)" % url)
|
||||
webbrowser.open(url)
|
||||
|
||||
|
||||
def setup_backend(serve=True, host=DEFAULT_HOST, port=DEFAULT_PORT, debug=False, view=True):
|
||||
"""Run the server of the gdb gui"""
|
||||
global app, gdb
|
||||
global gdb
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
gdb = GdbController()
|
||||
app.secret_key = 'iusahjpoijeoprkge[0irokmeoprgk890'
|
||||
app.debug = debug
|
||||
app.config['TEMPLATES_AUTO_RELOAD'] = True
|
||||
|
||||
if serve:
|
||||
extra_files = []
|
||||
for dirname, dirs, files in os.walk(TEMPLATE_DIR):
|
||||
for filename in files:
|
||||
filename = os.path.join(dirname, filename)
|
||||
if os.path.isfile(filename):
|
||||
extra_files.append(filename)
|
||||
app.run(port=port, extra_files=extra_files)
|
||||
if view:
|
||||
open_browser(host, port)
|
||||
app.run(host=host, port=port, extra_files=get_extra_files())
|
||||
|
||||
|
||||
def main():
|
||||
"""Entry point from command line"""
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--port", default=5000)
|
||||
parser.add_argument("--port", default=DEFAULT_PORT)
|
||||
parser.add_argument("--host", default=DEFAULT_HOST)
|
||||
parser.add_argument("--debug", action='store_true')
|
||||
parser.add_argument("--view", action='store_true')
|
||||
args = parser.parse_args()
|
||||
setup_backend(port=args.port, debug=args.debug)
|
||||
setup_backend(serve=True, host=args.host, port=args.port, debug=args.debug, view=args.view)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -1,23 +1,3 @@
|
|||
backports.shutil-get-terminal-size==1.0.0
|
||||
click==6.6
|
||||
decorator==4.0.10
|
||||
Flask==0.11.1
|
||||
ipdb==0.10.1
|
||||
ipython==5.1.0
|
||||
ipython-genutils==0.1.0
|
||||
itsdangerous==0.24
|
||||
Jinja2==2.8
|
||||
MarkupSafe==0.23
|
||||
pathlib2==2.1.0
|
||||
pexpect==4.2.1
|
||||
pickleshare==0.7.4
|
||||
prompt-toolkit==1.0.7
|
||||
ptyprocess==0.5.1
|
||||
pygdbmi==0.0.1.9
|
||||
Pygments==2.1.3
|
||||
pyjade==4.0.0
|
||||
simplegeneric==0.8.1
|
||||
six==1.10.0
|
||||
traitlets==4.2.2
|
||||
wcwidth==0.1.7
|
||||
Werkzeug==0.11.11
|
||||
|
|
3
setup.py
3
setup.py
|
@ -3,7 +3,7 @@ import sys
|
|||
|
||||
# from distutils.core import setup,
|
||||
EXCLUDE_FROM_PACKAGES = []
|
||||
version = '0.0.0.3'
|
||||
version = '0.0.0.4'
|
||||
|
||||
|
||||
class TestCommand (Command):
|
||||
|
@ -42,6 +42,7 @@ setup(
|
|||
install_requires=[
|
||||
'Flask>=0.11.1',
|
||||
'pygdbmi>=0.0.1.9',
|
||||
'pyjade>=4.0.0'
|
||||
],
|
||||
classifiers=[
|
||||
'Intended Audience :: Developers',
|
||||
|
|
Loading…
Reference in a new issue