【问题标题】:Is it possible to do hot code swapping in C?是否可以在 C 中进行热代码交换?
【发布时间】:2010-10-19 23:05:40
【问题描述】:

这个

en.wikipedia.org/wiki/Hot_swapping#cite_note-1

说 VS 可以在其调试器的帮助下做到这一点。 gdb 是否提供类似的功能?

这是我能找到的最接近的,但似乎还没有准备好使用:

http://www.aitdspace.gr/xmlui/handle/123456789/219

dlopen/dlsym/dlclose 也很接近,但不适用于 -lmylib 引用的库(引用计数永远不会为 0)。

我考虑过的替代方案:

1) 使用 -Wl,-wrap,foo 和 __wrap_foo() { func = dlopen();函数(); }

2) 使 libfoo.so 成为共享库,当我们需要热交换时,我们 dlopen(RTLD_GLOBAL) 来加载新代码并为下一次调用 foo() 提供更新的符号;

1) 效果不是很好,因为它需要我枚举所有我想热插拔的函数,它们都是。

2) 不能很好地工作,因为调用 foo() 时,会加载新代码,但 foo 永远拥有对该符号的引用。多次调用 dlopen 会使 foo 被重新评估。

【问题讨论】:

标签: c gcc gdb hotswap


【解决方案1】:

您可能对 Ksplice 感兴趣。这是一项源自 MIT 的技术,它允许将软件补丁应用到 Linux 内核而无需重新启动。这与应用安全更新最相关:

http://www.ksplice.com/paper

【讨论】:

    【解决方案2】:

    您当然可以自己破解一个系统,在该系统中存储函数指针列表,并可以更改这些指针以指向您当时使用 dlopen() 的任何库。

    您是对的,没有任何简单的方法可以拦截对具有固定链接的例程的调用。您总是可以通过程序集跳转到另一个例程来破坏例程的开始,但这可能很危险(并且不是 C)。

    也许一个在你的代码中很弱而在 dlopen()'d 库中很强大的符号会起作用?

    在任何这些情况下,您都必须处理旧代码当前正在运行的情况。这也不是一件容易的事,除非你在你的程序中有一些点你知道在你想要交换的库中没有线程。

    【讨论】:

    • 有没有办法“取消定义”一个符号? dlopen(RTL_GLOBAL) 全局定义符号,但仅适用于在它之后加载的库。如果我要 dlopen(RTL_GLOBAL) 多次进行热插拔,我需要将符号“忘记”才能重新加载。想法?
    • 你可以从 gdb 自己破解 PLT。
    【解决方案3】:

    我发现最接近的是 oracle developer studio 附带的 solari dbx,但是 dev studio 在 linux 和 solaris 中都使用 dbx,只有 solaris 版本支持“编辑并继续”或“热代码交换”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-29
      • 1970-01-01
      • 2013-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多