现代版本的 gdb 允许集成 python 代码以“ pretty-print ”复杂的数据结构。对于 C++ 的 STL 类以及一些更常见的 boost.org 类型,有一些非常 pretty-print 实现。
在网络编程中,经常会遇到select/poll调用。 poll() 使用数据结构数组,而 select() 使用 fd_set。
有没有人遇到过fd_set 的 pretty-print 实现,最好是可移植的,但即使是特定于平台的也可以。理想情况下,它是 linux/x86,但我愿意接受任何东西并希望能够适应。
最佳答案
好吧,这是我写的东西,它似乎在 Linux 下对我有用。让我知道它是否适合您:
anonprint.py
import gdb
class fd_set_printer:
"""
Prints an fd_set, which is normally an opaque
array of ints, each bit representing one file descriptor
"""
def __init__(self, val, val_array):
self.val = val
self.val_array = val_array
@staticmethod
def find_set_bits(bit_array):
"""
Finds set bits in a long bit list.
Expects a gdb.Value which contains a C array,
such as int[10], and treats it as a bitlist
of int_size * 10 bits long. Returns an array of
bit positions, starting with 0, for which the bits
are on.
e.g. for int foo[] = [1, 6], it will return [ 0, 33, 34 ]
The array should be given as a gdb.Value
"""
set_bits = []
bits_length = bit_array[0].type.sizeof * 8
current_bit = 0
# Can not use 'for current_byte in gdb.Value:' even if
# gdb.Value.type.code == gdb.TYPE_CODE_ARRAY
# So iteration happens this ugly C-style way
for current_byte_pos in xrange(*bit_array.type.range()):
current_byte = bit_array[current_byte_pos]
for bit in xrange(0, bits_length):
bit_mask = 1 << bit
if bit_mask & current_byte == bit_mask:
set_bits.append(current_bit)
current_bit += 1
return set_bits
def to_string(self):
fd_list = self.find_set_bits(self.val_array)
if len(fd_list) == 0:
output = "Empty file descriptor set."
else:
output = "File descriptor set: "
output += ', '.join(map(str, fd_list))
return output
def anon_struct_lookup_function(val):
"""
Checks if the given value looks like an fd_set.
If it does, delegates printing to the printer
"""
lookup_tag = val.type.tag
if lookup_tag == None:
return None
if lookup_tag != "<anonymous struct>":
return None
fields = val.type.fields()
val_array = None
if len(fields) == 1 and fields[0].name == 'fds_bits':
val_array = val['fds_bits']
elif len(fields) == 1 and fields[0].name == '__fds_bits':
val_array = val['__fds_bits']
if not val_array is None:
return fd_set_printer(val, val_array)
return None
def add_fd_set_printer(obj = gdb):
"Adds the fd_set pretty printer to the given object"
obj.pretty_printers.append(anon_struct_lookup_function)
然后让你的~/.gdbinit:
python
import sys
sys.path.insert(0, '/home/user/anonprint_py_directory_here')
from anonprint import add_fd_set_printer
add_fd_set_printer()
end
这是我第一次尝试通过 Python 与 gdb 内部交互,因此欢迎评论和建议。
关于python - 有人有 Linux 上 fd_set 的 gdb pretty-print 代码吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6832213/
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru
我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的
几个月前,我读了一篇关于rubygem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:
我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur
我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.