【问题标题】:Detect write to string检测写入字符串
【发布时间】:2012-02-16 09:02:53
【问题描述】:

有没有办法让我在不使用 mprotect(我不能使用)的情况下检测/启动-crash-on 写入字符串?

目前我只能在以下读取中检测到写入,但这为时已晚(以下读取可能来自完全不同的库)。

注意:由于优化器在进程内存中移动字符串,因此使用带有观察点的 gdb 失败。

编辑:有问题的变量是一个类成员 (char*),它包含一些元数据作为字符串的前缀。字符串是需要不可变的部分,前缀必须是可写的。我在类静态哈希中拥有数百万个这样的对象,并且可以从我们代码中的几乎任何地方访问它们。

【问题讨论】:

  • 在未优化的代码上使用 gdb 观察点怎么样?
  • 因为我无法在另一台机器上重现错误并将所有 libs\execs 替换为未优化将需要重新安装操作系统(这是非常低级的代码)
  • watch myString 不是独立于优化器将您的字符串 myString 放置在哪里吗?弄清楚myString在内存中的位置不是调试器的头疼吗?
  • 是的,但我在看具体的内存地址。字符串本身不是问题,而是其中的一个小节。如果我看一个内存地址“看”不能说明优化。
  • @Neowizard 您能否发布一些代码,以便我们可以推断出您要查看的变量的更多信息? cos,如果它是一个全局变量,那么你可以检查你的.map文件中的变量的确切地址,然后在GDB中使用它?

标签: c string memory


【解决方案1】:

您可以尝试将写入内存的所有代码包装在预处理器宏中,以检查您正在使用的地址,但由于大多数人喜欢使用裸露的指针(而不是封装事物的库调用),它可能会付出很多努力。

唯一的其他选项是mprotect(2) 或 GDB,它们都使用 CPU 的特殊部分来监视地址总线以访问相关内存。

由于您也不能使用它,最后的选择是将代码打印在纸上,然后坐在安静的角落里花几天时间阅读它。这通常会奏效,但大多数人会回避这种努力(而且因为它看起来不像“真正的”工作;-)。

【讨论】:

  • 我很想看看所有相关的代码,但它远远超过了几百万行潜在的代码。目前我正在尝试挑出有罪的图书馆来缩小搜索范围。
  • 如果总是同一个字符串出现乱码,那么有问题的代码必须以某种方式获取它的地址。这意味着它不能与创建/使用字符串的代码完全无关。
  • 没错,这是同一个过程,但它是一个巨大的过程。无论如何,我确实设法将其缩小到相关的流程,从那里开始,只需非常注意阅读代码......对我来说,它看起来像“真实”(并且最终非常有效)的工作:)。
  • 代码审查是查找和修复错误的最经济有效的方法 (en.wikipedia.org/wiki/Code_review)。我的讽刺是反对“阅读”不是“工作”的普遍误解:-)
【解决方案2】:

我不确定 gdb 中是否有类似于 dbx 中的“trace”的命令,但我记得在 dbx 中使用了一个名为“trace”的命令,该命令可用于跟踪代码中的各个变量,它会提示您何时变量值在执行过程中发生变化。

【讨论】:

  • trace 不会按照您在此处所说的进行。根据 DBX docs-trace-Have tracing information printed when the program is executed。事实上,stop <variable> 就是这样做的!参考 DBX docs-stop- Stop execution when the given line is reached,procedure or function entered, variable changed,module loaded or unloaded, or condition true 和 watch 是 GDB 中最接近 stop 的等价物
  • 是的,跟踪信息意味着它在程序执行时特定变量中的值发生变化时打印。如果您希望程序在变量中的值更改后立即停止,则可以使用停止。每次变量值更改时,trace 都会继续执行打印。
猜你喜欢
  • 2012-02-17
  • 1970-01-01
  • 2015-02-09
  • 2010-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多