美文网首页Python学习资料整理
用python在gdb中实现一个简单服务器

用python在gdb中实现一个简单服务器

作者: dounine | 来源:发表于2019-08-03 23:13 被阅读14次

0. 前言

gdb是一个十分强大的调试器,而它又提供给python扩展的gdb模块。但是,该模块只有在gdb中,才能被成功导入。

import gdb

运行上述代码,报错显示没有gdb模块。因为只有在gdb加载该python文件时,才能运行成功:

(gdb) source xxx.py

为了解决这个问题,可以利用python语言的强大,通过socket套接字编写,在gdb中开启一个服务器,从而到达外界与gdb之间的交互。

1. 代码示例

import gdb
import socket

# TCP服务端
def main():

    #创建一个socket对象,AF_INET指定使用IPv4协议(AF_INET6代表IPV6),SOCK_STREAM指定使用面向流的TCP协议
    tcp_serve_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp_serve_socket.bind(('localhost', 8001))   # 绑定本地ip和端口
    tcp_serve_socket.listen(128)                # 开始监听端口,数字表示等待连接的最大数量

    # 循环目的:多次调用accept为多个客户服务
    while True:
        print('等待一个新请求到来....')
        tcp_client_socket, client_addr = tcp_serve_socket.accept()
        print('一个新请求到来,来自:%s' % str(client_addr))

        recv_data = tcp_client_socket.recv(1024).decode('utf-8')   # 从客户端接受消息,最多1024字节。recv_data为字节类型,.decode()将recv_data转化成字符型
        print('请求发送的命令是%s' % recv_data)

        retMsg = ''
        if recv_data == 'start':
            print('send start to gdb')
            retMsg = gdb.execute('start', to_string=True)
        elif recv_data == 'continue':
            print('send continue to gdb')
            retMsg = gdb.execute('c', to_string=True)
        else:
            print('no this commond')
        print(retMsg)

        tcp_client_socket.send(retMsg.encode('utf-8'))  # 将字符串进行字节编码

        # 关闭与客户端的连接
        tcp_client_socket.close()
        print('请求响应完毕')

    tcp_serve_socket.close()

if __name__ == '__main__':
    main()

通过socket模块,开启一个tcp服务器,然后监听一个端口,接收客户端的请求,并对请求做出响应。

过程中,通过gdb模块中提供给pythonapi,进行对gdb的调用,如:gdb.execute('start', to_string=True) 执行start命令,并返回字符串。更多api官方文档

2. 运行与结果

假如实现了gdb服务器的代码文件为xxx.py,所在路径为yyy

运行方法为:

gdb

进入gdb命令行界面,然后:

(gdb) source xxx.py

或者:

echo "source yyy/xxx.py" >> ~/.gdbinit
gdb

最终结果为:

QQ截图20190406225438.png

3. 问题

虽然通过python编写socket服务器,可以实现外界与gdb的交互。但是,这样不优雅,也比较浪费。

同时,在gdb中实现的这个服务端,只是运行当前gdb中的一个扩展。而一个gdb同一时刻只能调试一个文件,该服务器又不可能让外层gdb多线程进行。

所以,任意一个用户访问,都只能得到当前gdb调试的进度和状态。也就是说,它只能为一个用户服务

而要为多用户服务,必须开启多个gdb服务端,但如果只是主机间的进程交互的话,这样是十分低效的。

更高效的方法应该是,用进程间通讯代替tcp通讯。

4. 更多内容

https://github.com/gu-team/gdbServer

相关文章

网友评论

    本文标题:用python在gdb中实现一个简单服务器

    本文链接:https://www.haomeiwen.com/subject/fzosdctx.html