python断点调试从哪里看数据_断点调试和日志调试之间的平衡点 --- 函数计算调试之Python篇...

本文探讨了在没有IDE的情况下,如何在断点调试和日志调试之间找到平衡,以快速定位Python脚本中的错误。通过使用tracebackturbo库,可以在异常发生时获取完整的函数堆栈和局部变量信息,从而提供更精确的错误定位。相比全日志,这种方法在报错时能提供更多信息,且仅在出错时记录,减少了性能影响。然而,它可能暴露出敏感信息。实现原理涉及栈帧结构和运行时信息的获取。
摘要由CSDN通过智能技术生成

原标题:断点调试和日志调试之间的平衡点 --- 函数计算调试之Python篇

云栖君导读:本文将介绍一种结合函数堆栈,捕获栈中local变量的方式来达到快速定位bug的目的。

Python 调试篇

很多初学者喜欢使用断点调试,方便之处是可以查到运行期各种栈内的变量值,来帮助debug。

但这一点如果脱离了IDE,其实是非常困难的。在服务器的执行过程中,更需要使用attach的方式才可能做到这点。

对于一些生产环境的错误定位,用断点调试几乎是完全不可能的。

而使用日志来做错误定位,对于一些脚本语言,尤其弱类型的语言,当你将一个变量经过多个函数传递的过程中,如果传递过程中不小心有拼写错误,只有最后使用到这个变量的地方才报出错误来,使用日志的方式要定位什么地方写错了非常困难,对于生产环境中多分支调用链极长的逻辑,更是难上加难。

本文将介绍一种结合函数堆栈,捕获栈中local变量的方式来达到快速定位bug的目的。

相对于其他runtime,python可以获取到很多运行时信息。通常来说,通过异常捕获,python 默认的traceback 给出的栈和错误信息已经能帮助开发者调试了。但时常来说,这并不是万能的,偶尔会遇到一些问题,必须加日志才能解决。但如果开发者日志加得不够细,生产环境中也很难立即重现,此时有什么好办法呢?

下面我们通过一个简单的例子来讲解如何在断点调试和日志调试中找一个平衡点定位python脚本中的bug。

3ec634fd307d412f83200c05693ad548.png

假设 bar 中数组访问越界,实际的bug在c = a + b 那行,其实本应该是c = a - b,我们没有日志,此时如何定位到这个bug?

使用范例:

我们先创建代码目录:

复制粘贴以下代码到 ~/sandbox/fc/traceback/python/main.py

35e034d6f1b04b4c98dcdaf8e40b3bcd.png

然后切换到 ~/sandbox/fc/traceback 目录

执行 shell 命令: fcli shell,关于 fcli

执行下述命令,其中 -d python 指的是当前代码所在目录 python ,而 python2.7 指 python2.7 runtime

接下来我们使用 pip 安装 tracebackturbo 这个库

本地可以先做一下测试:

测试结果:

4a9fedca3d414851bd682c30703b2f2c.png

我们可以看到栈中每个local变量都已经被print了出来,在生产环境中,我们可以在 service 上设置 logstore,将这部分错误信息输出到日志服务。

比较

我们可以比较全日志 及 traceback 日志的优缺点:

全日志

优点

可以隐藏敏感信息

对于无报错,无异常抛出的代码也可以做有效记录

缺点

日志可能记录不全,线上问题调查很困难

需要记录大量日志,太多的日志会导致性能低下

traceback 日志

优点

报错时可以拿到整个栈的信息,分析问题可以非常全面

日志简洁,在没有报错的时候,不会有其他信息干扰

由于只在报错才有日志,正常情况下只有try的开销,相对来说性能更高

缺点

局部变量中含有敏感信息,可能会暴露给日志查看人员

实现原理简介

接下来我们了解一下这个库的实现原理,简要提一下计算机系统运行时栈的结构:

栈结构

b0d994664ae84dc5a87c0b0eab728866.png

frame 的结构

69fa7aee84bb41d59e08930a930d06ff.png

通常来说,各类计算机语言的 runtime 实现(实现细节及名称可能各不相同)都会包含上述信息。

function proto 结构

d741c047f71b4d4e8a231ec28a7de70d.png

每个变量包含

声明行

相对于frame 基地址偏移

局部变量声明周期对应指令集

对于任何一个未 return 的函数,如果我们拿到了这个栈,就可以获取到栈顶的若干 frame ,找到function proto,就可以找到各个局部变量的偏移,通过 frame 基地址相加,我们就可以得到每个局部变量的地址,获取到每个变量的内容。

相关链接

lua traceback https://github.com/rocaltair/ltrace

lua 调用动态链接库 crash https://github.com/rocaltair/lua-coredump

责任编辑:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值