我有一个遗留的 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_Main 和 Py_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/
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
我有一个在Linux服务器上运行的ruby脚本。它不使用rails或任何东西。它基本上是一个命令行ruby脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的