跨版本线路匹配
我正在考虑如何进行自动错误跟踪,作为其中的一部分,我想知道有什么可用于匹配源代码行号(或者通过诸如 addr2line
) 在一个版本的程序中复制到另一个版本的同一行。 (假设所有内容都在某种源代码管理中并且可用于我的代码)
最简单的方法是在文件上使用 diff 工具/lib 并对行号跨度进行一些数学计算,但这有一些限制
- :不处理跨文件运动。
- 它可能无法很好地处理已更改的行。
- 它不会查看中间版本中可用的信息。
- 当 diff 工具出错时,它无法提供手动修补行的方法。
- 这有点笨重
在我开始深入开发更好的东西之前:
- 已经有什么可以做到这一点?
- 类似的系统有哪些我没有想到的功能?
I'm considering how to do automatic bug tracking and as part of that I'm wondering what is available to match source code line numbers (or more accurate numbers mapped from instruction pointers via something like addr2line
) in one version of a program to the same line in another. (Assume everything is in some kind of source control and is available to my code)
The simplest approach would be to use a diff tool/lib on the files and do some math on the line number spans, however this has some limitations:
- It doesn't handle cross file motion.
- It might not play well with lines that get changed
- It doesn't look at the information available in the intermediate versions.
- It provides no way to manually patch up lines when the diff tool gets things wrong.
- It's kinda clunky
Before I start diving into developing something better:
- What already exists to do this?
- What features do similar system have that I've not thought of?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为什么需要这样做?如果您使用适当的源版本控制,您应该可以访问旧版本的代码,您可以简单地提供一个链接,以便人们可以在其原始位置看到错误。事实上,我看到这个系统的主要问题是错误可能已经被修复,但你的自动线路跟踪代码会指向一行并说那里有一个错误。似乎这个系统的构建会很痛苦,并且在实践中无法提供很多帮助。
Why do you need to do this? If you use decent source version control, you should have access to old versions of the code, you can simply provide a link to that so people can see the bug in its original place. In fact the main problem I see with this system is that the bug may have already been fixed, but your automatic line tracking code will point to a line and say there's a bug there. Seems this system would be a pain to build, and not provide a whole lot of help in practice.
我的建议是:您应该使用唯一标识符来装饰每个断言(或其他感兴趣的行),而不是尝试跟踪行号(正如您所观察到的,随着软件更改,行号可能会很快失去同步)。
假设您使用的是 C,对于断言,这可能就像将
assert(x == 42);
更改为assert(("check_x", x = = 42));
-- 由于 C 中逗号运算符的语义以及字符串文字始终计算为 true 的事实,这在功能上是相同的。当然,这意味着您需要先验地识别那些您希望跟踪的项目。但鉴于没有普遍可靠的方法来匹配跨版本的源行号(我的意思是,对于您可以提出的任何机制,我相信我可以提出一种该机制做错误事情的情况),我认为这是你能做的最好的事情。
另一个想法:如果您使用 C++,则可以使用 RAII 来跟踪动态范围非常优雅。基本上,您有一个 Track 类,其构造函数采用描述范围的字符串并将其添加到当前活动范围的全局堆栈中。
Track
析构函数将顶部元素从堆栈中弹出。最后的成分是一个静态函数Track::getState()
,它只是返回所有当前活动范围的列表——这可以从异常处理程序或其他错误处理机制中调用。My suggestion is: instead of trying to track line numbers, which as you observed can quickly get out of sync as software changes, you should decorate each assertion (or other line of interest) with a unique identifier.
Assuming you're using C, in the case of assertions, this could be as simple as changing something like
assert(x == 42);
toassert(("check_x", x == 42));
-- this is functionally identical, due to the semantics of the comma operator in C and the fact that a string literal will always evaluate to true.Of course this means that you need to identify a priori those items that you wish to track. But given that there's no generally reliable way to match up source line numbers across versions (by which I mean that for any mechanism you could propose, I believe I could propose a situation in which that mechanism does the wrong thing) I would argue that this is the best you can do.
Another idea: If you're using C++, you can make use of RAII to track dynamic scopes very elegantly. Basically, you have a
Track
class whose constructor takes a string describing the scope and adds this to a global stack of currently active scopes. TheTrack
destructor pops the top element off the stack. The final ingredient is a static functionTrack::getState()
, which simply returns a list of all currently active scopes -- this can be called from an exception handler or other error-handling mechanism.