草庐IT

python - 遗留 GDB 脚本中堆栈跟踪的停止条件

coder 2024-02-24 原文

我有一个遗留的 GDB 命令脚本,用于基于 Python 2.6 源代码附带的 GDB 脚本获取 Python 堆栈跟踪(所以不允许超链接,但这是 URL:http://#%20http ://svn.python.org/view/*checkout*/python/branches/release26-maint/Misc/)

该脚本有一个 while 循环,它基于要退出的程序计数器进行相当脆弱的检查,这(如评论中的原始代码中所述)可能仅适用于直接运行 Python 的情况,如果解释器从 C/C++ 应用程序中启动。

现有的 while 循环如下所示:

while $pc < Py_Main || $pc > Py_GetArgcArgv
    # ...
    # code for extracting Python stack from local vars in relevant frames
    # of C stack
    # ...

    up-silently 1

对于我要调试的程序,针对 Py_MainPy_GetArgcArgv 的检查不会很好地工作,所以我正在寻找一个循环条件,它将当它到达 main 时评估为 false。

所以我一直在考虑使用程序计数器、帧指针和堆栈指针的想法,因为如果 up-silently 失败,它们将具有相同的他们以前的值,这意味着我在堆栈的顶部,如下所示:

set $oldpc = -1
set $oldfp = -1
set $oldsp = -1
while !($oldpc == $pc && $oldfp == $fp && $oldsp == $sp)
    # ...
    # code for extracting Python stack from local vars in relevant frames
    # of C stack
    # ...

    set $oldpc = $pc
    set $oldsp = $sp
    set $oldfp = $fp
    up-silently 1

我认为这应该可以解决问题,初步检查表明它工作正常。但是,我不太熟悉编译器可以进行的各种优化,而且我担心可能存在极端情况,在这种情况下,它们可能在堆栈中间的某个地方有效地相同。

看起来 $fp 对于帧指针已被优化掉的调用可以为零(例如,通过使用 GCC 使用 -g -O3 进行编译)。我也不确定是否可以依赖 $pc 来有所不同,尤其是在递归调用发生的情况下。我希望 $sp 会有所不同,同时仍有有效的堆栈要处理,但我模糊地怀疑与 tail recursion 相关的优化可能导致 $sp 相同。

如有任何建议,我们将不胜感激。

具体问题:

问题 1:在遗留(非 Python)GDB 脚本中是否有更好的方法来确定您是否位于堆栈的顶部?

问题 2:我对 $sp$pc$fp 的假设对大多数人是否成立还是所有的优化场景?

最佳答案

所以我没有问题 1 的答案,但我想我可以部分回答问题 2

Tail recursion确实会重用现有的堆栈指针和帧指针。这对于堆栈跟踪意味着,对同一个优化尾递归函数的多次调用只会在 GDB 中显示一次,因为(显然)堆栈指针被重用(并且没有新的堆栈或帧指针被压入)。

这似乎意味着您可以检查 $sp 的先前和当前值来确定停止条件。不幸的是,堆栈中间的 $sp 值可能是相同的。当一些函数调用被优化掉时,这似乎会发生。

所以我在问题中提出的停止条件可能相当脆弱,尽管它适用于几个现实世界的例子。

关于python - 遗留 GDB 脚本中堆栈跟踪的停止条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22856807/

有关python - 遗留 GDB 脚本中堆栈跟踪的停止条件的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  3. ruby-on-rails - 独立 ruby​​ 脚本的配置文件 - 2

    我有一个在Linux服务器上运行的ruby​​脚本。它不使用rails或任何东西。它基本上是一个命令行ruby​​脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg

  4. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  5. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  6. ruby - 定义方法参数的条件 - 2

    我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano

  7. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  8. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  9. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  10. python - 如何读取 MIDI 文件、更改其乐器并将其写回? - 2

    我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的

随机推荐