调试会话的长期影响,即使在分离后也是如此 (linux)

Long-term effects of a debugging session, even after detaching (linux)

提问人:ABu 提问时间:8/9/2023 最后编辑:ABu 更新时间:8/10/2023 访问量:29

问:

让我们从考虑动态加载的库开始。据我了解,例如,在输出中,您通常会看到一个可写部分,指向实际上标记为匿名的文件。例如:smaps.so

7fa9942af000-7fa9942f1000 rw-p 03d98000 fd:0c 131627                     /usr/share/oracle/19.0.0/client_1/lib/libclntsh.so.19.1
Size:                264 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Rss:                   4 kB
Pss:                   4 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         4 kB
Referenced:            4 kB
Anonymous:             4 kB
LazyFree:              0 kB
AnonHugePages:         0 kB
ShmemPmdMapped:        0 kB
FilePmdMapped:         0 kB
Shared_Hugetlb:        0 kB
Private_Hugetlb:       0 kB
Swap:                188 kB
SwapPss:             188 kB
Locked:                0 kB
THPeligible:    0
ProtectionKey:         0
VmFlags: rd wr mr mw me ac sd

此地址范围包含一个匿名页(匿名:4kB),可能是由于以下事件序列:

  • 该范围可能是指库中包含全局变量的部分。这就是页面被标记为可写(权限 rw-p)的原因。.bss
  • 全局变量可能已被修改,因此映射的页面不再与磁盘中的相应页面匹配。
  • 内核在类似写入时复制的策略下分配一个新页面。该页面现在是匿名的,因为它不再与相应的文件支持的页面匹配。
  • 如果将来的某个时候有一些页面回收,那么该页面(因为它现在是匿名的)可以被交换掉,而不是像未修改的文件支持的页面那样被丢弃。

还行。如果我将相同的逻辑应用于创建断点的调试器,则在我的脑海中可能会发生以下事件序列:

  • 二进制文件的 .text 部分是只读的,但由于断点是通过调用 而创建的,因此在内核模式下执行,因此内核可以修改页面,因为内核绕过权限。ptrace
  • 调试器实际执行的操作是将断点位置的指令替换为陷阱指令,因此包含被替换指令的相应页面已被修改,因此它变得匿名,如上例所示。ptrace
  • 当调试器分离并退出时,如果调试器没有错误,它将删除所有断点,从而还原对文本所做的所有更改。
  • 内核不知道页面已恢复到其原始状态(它刚刚见证了一组修改),因此即使在调试器退出后,页面仍保持匿名。

这意味着调试器将导致进程的内存布局发生更改,即使在它退出后也是如此。这意味着,例如,在页面回收的情况下,成为匿名的页面将被交换掉,而不是像在正常情况下那样被丢弃。这会对系统性能造成影响,因为内核必须管理比以前更多的匿名页面的生命周期(特别是如果在调试会话之后,用户创建了大量断点,从而分散到多个页面)

如果我对情况的理解是正确的,那么即使在完成调试会话后,调试器是否也会对性能造成影响?

注意:我对另一个案例感到困惑:

7fa994544000-7fa994545000 r--p 0002c000 103:04 10234                     /usr/lib64/ld-2.28.so
Size:                  4 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Rss:                   4 kB
Pss:                   4 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         4 kB
Referenced:            4 kB
Anonymous:             4 kB
LazyFree:              0 kB
AnonHugePages:         0 kB
ShmemPmdMapped:        0 kB
FilePmdMapped:         0 kB
Shared_Hugetlb:        0 kB
Private_Hugetlb:       0 kB
Swap:                  0 kB
SwapPss:               0 kB
Locked:                0 kB
THPeligible:    0
ProtectionKey:         0
VmFlags: rd mr mw me dw ac sd

该页面是只读的、文件支持的,并且仍然是匿名的。这怎么可能?

C Linux 调试 内存 GDB

评论

1赞 shellter 8/10/2023
最好包括一个最小的可重复示例,以便读者可以在他们的个人环境中尝试。您还应该选择/包含一种编程语言,因为许多读者忽略了 linux 标记的问题,因为有太多偏离主题的“我无法安装 kali-linux 环境”的帖子。祝你好运。

答: 暂无答案