2015-01-09 53 views
2

是否有允许运行时结构内省的C语言工具?在运行时C结构内省

上下文是这样的: 我有一个响应外部事件的守护进程,并且对于每个事件我们都带着一个执行上下文结构(“context”)。上下文很大很混乱,并且包含对各种状态的引用。

事件处理完成后,我希望能够通过过滤器运行上下文,并且如果它符合某些条件集,请删除日志消息以帮助进行调试。但是,因为我希望将其用于现场调试,所以我不知道在运行时间之前过滤哪些条件是有用的。

我的理想解决方案将允许用户从本质上写出一个C风格的布尔表达式并让程序使用它。喜欢的东西:已被到处滥用

activate_filter context.response_time > 4.2 && context.event.event_type == foo_event 

想法到目前为止,包括:

  • 提供了一组有限的,我们知道如何访问字段。
  • 将所有相关的结构包装在运行时生成自检工具的某种宏中。
  • 编写一个知道哪里(版本化)头文件存在的python脚本,生成C代码并将其编译为一个dll,然后该守护程序将加载并用作过滤器。显然这种方法有一些额外的安全考虑。

在我开始一些疯狂的设计鹅追逐之前,有没有人知道这种事情在野外的例子?我穹顶了一些谷歌搜索,但没有提出太多。

+3

没有内置的内省。你可以设计出近似自省的系统(静态定义的结构来描述其他结构),'sizeof'运算符和''中的'offsetof'宏可以提供帮助。类型编码是一个完全独立的bag'o'worms。 – 2015-01-09 21:52:07

+1

你可能会发现[有没有在循环中打印'struct'成员的方法,而不用C中每个成员的名字?](http://stackoverflow.com/questions/27496245/is-there-a-way-to-print -struct-members-in-a-loop-without-naming-each-member-in -c/27497861#27497861)对你有帮助,否则你可能不会。 – 2015-01-09 21:55:55

回答

0

您可能从错误的一面接近了这个问题。

日志记录通常用于帮助调试。该程序将各种事件写入日志文件。提取有趣的条目过滤应用于日志文件。

有时一个程序产生的事件太多;日志库通常通过提供冗长控制来解决这个问题。基本上,日志功能需要一个额外的参数来告诉当前消息的详细程度。如果该值高于全局配置的阈值,则该消息被丢弃。一些图书馆甚至允许以每个模块为基础控制详细程度(例如:谷歌日志)。

另一种可能的方法是利用调试器的强大功能,因为调试器可以访问各种元信息。可以为任意条件创建一个条件断点测试变量。一旦程序停止,可以从示波器提取任何信息。这可以使用调试器提供的脚本工具来自动执行(gdb有很好的功能)。

最后,有一些工具可以生成粘合代码,以使用脚本语言的C库。 SWIG就是一个例子。它分析头文件并生成代码,允许脚本语言调用函数,访问结构字段等。

您的过滤器表达式将成为Lua(同时支持其他脚本语言)中的程序。你调用这个程序传入指向执行上下文结构(“上下文”)的指针。由于SWIG生成的访问器Lua程序可以检查结构中的任何字段。

+0

好得多,学习一个工具而不是学习lex和yacc和xml解析等。 – user3629249 2015-01-09 23:28:00

+1

感谢您的回应!你说得对,这是对记录的非典型使用。不幸的是,这个程序每秒处理数十万个事件,并且记录所有这些事件都会对性能产生巨大影响。我已经使用基本过滤器进行了一些实验,并且它们似乎没有相同的减速过程。我怀疑在调试器中运行会有类似的性能影响,而且我们希望在客户站点的实时服务器上使用此工具。但我一定会检查出SWIG。 – Dan 2015-01-12 18:54:14

1

我也建议从另一个角度来解决这个问题。在你的问题的关键词是:

的背景是大而凌乱

而这正是问题的。一旦你清理了这些,你可能会想出一个干净的日志记录工具。

考虑以一些简单易用的格式重新定义您的上下文struct中的所有字段,如XML。一个简单的XML模式,它列出了结构的所有成员,它们的类型,以及其他一些元数据,甚至包含记录该字段的注释。

然后,将一个快速而脏的样式表放在一起,该样式表读取XML文件并生成一个可编译的C结构体,您的代码实际使用该结构体。然后,生成一个不同的样式表,用于生成robo生成的代码,枚举结构中的每个字段,并生成将每个字段转换为字符串的代码。

从此,用某种用户提供的过滤字符串栓上某种日志工具变得更容易。你必须想出一些解析任意过滤字符串的方法。了解lexyacc会派上用场。

这种性质的事情已经做过。

XCB library是X11协议的C客户端库。该协议定义了各种各样的二进制消息,这些消息本质上是简单的,客户端和服务器通过套接字相互抛掷。实现libxcb的方式是,所有X11消息及其内部的所有数据类型都在XML定义中描述,样式表robo-生成C结构定义以及解析它们的代码,并提供一个相当干净的C API解析并生成X11消息。