iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >用 Python 拓展 GDB(四)
  • 630
分享到

用 Python 拓展 GDB(四)

PythonGDB 2023-01-31 08:01:37 630人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

欢迎来到《用python拓展gdb》的最后一篇。第一篇结尾,我提到了通用语言相对于领域特定语言的一项优势,即在处理数据上更加灵活。其实通用语言还有着另一样优势,领域特定语言只能局限在宿主程序中使用,而通用语言则无此限制。对于通用语言来说,

欢迎来到《用python拓展gdb》的最后一篇。第一篇结尾,我提到了通用语言相对于领域特定语言的一项优势,即在处理数据上更加灵活。其实通用语言还有着另一样优势,领域特定语言只能局限在宿主程序中使用,而通用语言则无此限制。对于通用语言来说,gdb暴露的接口不过是又一个库而已。

在本篇中,我们会把Python当作一门“胶水语言”,A面是gdb的接口,B面是一个终端界面的程序。姑且把这个终端界面程序称之为gti(gdb's terminal interface)吧。我们会实现从gdb到gti的单向数据传输。每当gdb触发断点时,就在gti上自动输出各项相关信息。这两者间的通讯使用UDP协议。换言之,接下来要完成的是一个位于gdb内部UDP客户端,和监听指定端口的带终端界面的UDP服务端。

gdb 端实现

gdb端功能如下:

  1. 每当断点被触发时,通过gdb接口获取info breakpointsinfo args,以及info locals三者的值

  2. 把上述三者的值转换成JSON格式

  3. 通过UDP协议发送到端口9876

功能要求看上去很多,不过实现成代码其实也就二三十行:

import json
import Socket
import gdb


HOST = 'localhost'
PORT = 9876
SOCK = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
SOCK.connect((HOST, PORT))

def send_data(event):
    cur = event.breakpoints[0].location
    if cur is None:
        cur = event.breakpoints[0].expr
    local_vars = gdb.execute('info locals', to_string=True)
    args = gdb.execute('info args', to_string=True)
    bps = gdb.execute('info breakpoints', to_string=True)
    data = {
        'current': cur,
        'locals': local_vars,
        'args': args,
        'breakpoints': bps
    }
    data = json.dumps(data)
    SOCK.send(bytes(data, 'utf-8'))


gdb.events.stop.connect(send_data)

在此之前,需要设置一个监听9876端口的服务端,不然客户端这边就建立不了连接。运行nc -l 9876作为服务端的mock,暂时只需观察下发送过来的数据是否正确。

写一个自动化脚本,让gdb设置若干断点并运行,连续执行多次continue。你应该可以观察到接连有数据显示在nc的输出中:

$ nc -l 9876
{"locals": "pointers = ...

gti 端实现

gti 端功能如下:

  1. 监听端口9876

  2. 每当收到数据包时,提取出json格式的数据

  3. 根据收到的数据,重绘当前界面

在绘制终端界面时,我用的是自带的curses模块。在监听端口方面,我用的是python3.4之后才有的async模块。当然萝卜白菜,各有所爱,大可改用你自己喜欢的库。

#!/usr/bin/env python3
import asyncio
import curses
import json

def main():
    loop = asyncio.get_event_loop()
    # 1. 监听端口9876
    server = loop.create_datagram_endpoint(
        GtiProtocol, local_addr=('127.0.0.1', 9876))
    try:
        loop.run_until_complete(server)
        loop.run_forever()
    except KeyboardInterrupt:
        pass
    finally:
        curses.endwin()


class GtiProtocol(asyncio.Protocol):
    def __init__(self):
        self.ui = TextPad()

    def datagram_received(self, byte, _):
        "2. 将收到的数据从byte转成json"
        data = byte.decode()
        data = json.loads(data)
        self.ui.display(data)


class TextPad:
    def __init__(self):
        self.pad = curses.initscr()
        curses.start_color()

    def _addstr(self, text):
        self.pad.addstr(text, curses.A_BOLD)

    def display(self, data):
        "3. 根据给定的数据重绘界面"
        try:
            self.pad.erase()
            self._addstr('current: %s\n\n' % data['current'])
            for key, value in data.items():
                if key != 'current':
                    self._addstr('%s:\n' % key)
                    self._addstr(value)
                    self._addstr('\n')
            self.pad.refresh()
        except curses.error:
            pass


main()

现在可以用./gti.py来替换掉nc -l 9876,再重新运行gdb。你应该能看到,每当有新的断点触发时,./gti.py就会应用新的数据绘制界面。

顺便一提,使用curses模块纯粹是为了方便示范。curses提供的接口过于底层,许多细节方面都需要自己去抠。如果真的要开发实际可用的终端界面程序,建议使用诸如urwid这样的第三方包。

小结

如上面的例子所示,我们成功地用python实现了内嵌于gdb的客户端。该客户端可以向外界暴露出gdb调试时的信息。依据同样的思路,我们也可以在gdb内实现内嵌的服务端,这样外界就能动态修改gdb调试的方式。当然,这一切离不开python这把“瑞士军刀”。

《用python拓展gdb》系列到此就结束了。如果你正准备编写一个拓展,希望本教程可以教会相关的知识。如果你是一位C/C++开发者,希望本教程能够让你的工具箱增添新道具。如果你是想了解更多关于gdb调试的信息,希望今后遇到相关问题时能想起编写python拓展予以解决。

--结束END--

本文标题: 用 Python 拓展 GDB(四)

本文链接: https://www.lsjlt.com/news/193215.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 用 Python 拓展 GDB(四)
    欢迎来到《用python拓展gdb》的最后一篇。第一篇结尾,我提到了通用语言相对于领域特定语言的一项优势,即在处理数据上更加灵活。其实通用语言还有着另一样优势,领域特定语言只能局限在宿主程序中使用,而通用语言则无此限制。对于通用语言来说,...
    99+
    2023-01-31
    Python GDB
  • Python 拓展之迭代器
    写在之前 今天来讲讲「迭代器」的内容,其实已经拖了好多天了,感觉再不写就要忘记了。「迭代」相信对你来说已经不陌生了,我前面曾经专门用一篇文章来讲,如果你已经没有什么印象的话,就再点进去看看(零基础学习 Python 之初识迭代)。 迭代器...
    99+
    2023-01-30
    迭代 Python
  • 运维python拓展(一)request
    介绍python的requests模块是python一个强大的第三方HTTP请求库,简单易用安装: pip install requestsimport requestsurl='http://new.nginxs.net/ip.php' ...
    99+
    2023-01-31
    运维 python request
  • Python 拓展之特殊函数(lambd
    写在之前 今天给大家介绍几个比较特殊的函数,他们具有函数式编程的特点,有人将它们视为 Python 可进行 “函数式编程” 的见证,至于什么是函数式编程,不是本篇文章的重点,感兴趣的可以去了解一下。老读者可能都知道,我非常推崇 Pytho...
    99+
    2023-01-30
    函数 Python lambd
  • PHP中使用pthread拓展
    目录一. 线程的创建和使用1. Thread类2.Worker类二. PHP线程遇到的一些问题与注意点1.线程类的属性不能直接进行哈希表(数组)操作,如:2.线程类的属性不能是“闭包...
    99+
    2022-11-12
  • Kotlin拓展函数怎么用
    这篇文章主要介绍了Kotlin拓展函数怎么用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Kotlin拓展函数怎么用文章都会有所收获,下面我们一起来看看吧。原理拓展函数是kotlin里一个比较常用的特性,例如我...
    99+
    2023-06-29
  • SpringBootApplicationContextAware拓展接口使用详解
    近日沉醉于熟悉公司新项目的过程,不断地接触新的应用场景与实现技术,对于我是一种学不来的进步,实践是检验真理的唯一标准。我们今天就浅浅的谈一谈springboot提供的16个拓展接口之...
    99+
    2023-05-14
    SpringBoot ApplicationContextAware SpringBoot拓展接口
  • SpringBoot ApplicationContextAware拓展接口怎么使用
    这篇文章主要介绍“SpringBoot ApplicationContextAware拓展接口怎么使用”,在日常操作中,相信很多人在SpringBoot ApplicationContextAware拓展接口怎么使用问题...
    99+
    2023-07-06
  • SpringBoot ApplicationContextAware拓展接口如何使用
    本篇内容介绍了“SpringBoot ApplicationContextAware拓展接口如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读...
    99+
    2023-07-05
  • Python基础09 面向对象的进一步拓展
    我们熟悉了对象和类的基本概念。我们将进一步拓展,以便能实际运用对象和类。调用类的其它信息上一讲中提到,在定义方法时,必须有self这一参数。这个参数表示某个对象。对象拥有类的所有性质,那么我们可以通过self,调用类属性。...
    99+
    2023-06-02
  • Git文件常用操作总结及拓展
    目录1、Git本地版本库结构2、Git常用操作方法3、补充:添加多个文件到暂存区4、补充:提交操作未写备注5、补充:从工作区直接提交到版本库1、Git本地版本库结构 如下图所示: ...
    99+
    2022-11-13
  • 如何用GDB 排查 Python 程序故障
    如何用GDB 排查 Python 程序故障,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。某Team在用Python开发一些代码,涉及子进程以及设法消除僵尸进程的需求。实践中他们...
    99+
    2023-06-17
  • 使用Spring RestTemplate 详解实践使用及拓展增强
    目录RestTemplate 是什么?主要类和接口基础使用Get获取对象或对象集合Post 发送对象或集合上传文件上传多个文件Spring RestTemplate 拓展继承Rest...
    99+
    2022-11-12
  • C#反射调用拓展类方法实例代码
    目录C# 类拓展方法C#反射调用拓展类总结 今天封装Protobuf封包时候遇到一个问题; Protobuf的反序列化方法MergeFrom,是写在扩展类里的; C# 类拓...
    99+
    2022-11-13
  • 微信小程序开发拓展接口怎么用
    这篇文章主要为大家展示了微信小程序开发拓展接口怎么用,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带大家一起来研究并学习一下“微信小程序开发拓展接口怎么用”这篇文章吧。wx.arrayBufferToBase64(array...
    99+
    2023-06-26
  • 高效利用Golang Facade模式构建可拓展的系统
    使用Golang的Facade模式可以帮助构建可拓展的系统。Facade模式是一种结构型设计模式,它提供了一个统一的接口,用于访问系...
    99+
    2023-10-08
    Golang
  • vue使用GraphVis开发无限拓展的关系图谱的实现
    1、去GraphVis官网下载对应的js,新版和旧版的js有所不同,看自己需求引入旧版还是新版(GraphVis官方网址:http://www.graphvis.cn/) ...
    99+
    2022-11-12
  • Git用户签名的修改取消及优先级拓展教程
    目录1、修改用户签名2、取消用户签名3、用户签名的优先级4、总结本文用到的Git命令1、修改用户签名 其实很简单,就是重新执行git config命令,换个用户名和邮箱地址就可以了,...
    99+
    2022-11-13
  • vue中怎么利用GraphVis实现无限拓展的关系图谱
    本篇文章给大家分享的是有关vue中怎么利用GraphVis实现无限拓展的关系图谱,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。去GraphVis官网下载对应的js,新版和旧版的...
    99+
    2023-06-20
  • Git配置用户签名方式的拓展示例实现全面讲解
    目录1、配置Git签名(1)语法(2)配置系统用户签名(3)配置全局用户签名(4)配置本地用户签名2、查看三个配置文件的用户签名(1)语法(2)查看项目/仓库级别的配置文件信息(lo...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作