【发布时间】:2016-09-30 15:35:33
【问题描述】:
源码在这里:
#include <stdio.h>
#include <stdlib.h>
void main() {
int *a = malloc(sizeof(int));
*a = 11;
int b = 22;//on the stack
int pid = fork();
if (pid == 0) {
printf("pid=%d, a = %d, &a=%p\n", getpid(), *a, a);
printf("pid=%d, b = %d, &b=%p\n", getpid(), b, &b);
getchar();
*a = 33;// ===========cow=========happend here=====
b = 44;
printf("pid=%d, a = %d, &a=%p\n", getpid(), *a, a);
printf("pid=%d, b = %d, &b=%p\n", getpid(), b, &b);
} else {
printf("pid=%d, a = %d, &a=%p\n", getpid(), *a, a);
printf("pid=%d, b = %d, &b=%p\n", getpid(), b, &b);
}
pause();
}
这是将 33 写入 a 的那一行的 gdb 反汇编, 我在这里设置了一个断点。并启动这个程序。然后使用crash查看a
的物理地址 >│0x40073a <main+154> movl $0x2c,-0x20(%rbp) //copy on write happend here │
│0x400741 <main+161> mov -0x18(%rbp),%rax │
│0x400745 <main+165> mov (%rax),%ebx
a的线性地址是0x602010,所以使用vtop,我得到了:
我们可以看到它们都指向2a683010
的同一个物理地址 PID: 6468
COMMAND: "a.out"
TASK: ffff88007c317300 [THREAD_INFO: ffff880016728000]
CPU: 0
STATE: TASK_TRACED|TASK_WAKEKILL
crash> vtop 0x602010
VIRTUAL PHYSICAL
602010 2a683010
PML: 24e6f000 => 2409c067
PUD: 2409c000 => 7144067
PMD: 7144018 => 19847067
PTE: 19847010 => 800000002a683065
PAGE: 2a683000
PID: 6464
COMMAND: "a.out"
TASK: ffff880036992280 [THREAD_INFO: ffff880014e38000]
CPU: 0
STATE: TASK_TRACED|TASK_WAKEKILL
crash> vtop 0x602010
VIRTUAL PHYSICAL
602010 2a683010
PML: 36df9000 => 3a654067
PUD: 3a654000 => 1a71a067
PMD: 1a71a018 => 18f2a067
PTE: 18f2a010 => 800000002a683065
PAGE: 2a683000
在 gdb 中键入 ni(将 a 的值更改为 33)后,再次使用 vtop。我可以看到其中一个进程的物理地址发生了变化。
crash> vtop 0x602010
VIRTUAL PHYSICAL
602010 5d755010
PML: 24e6f000 => 2409c067
PUD: 2409c000 => 7144067
PMD: 7144018 => 19847067
PTE: 19847010 => 800000005d755067
PAGE: 5d755000
crash> vtop 0x602010
VIRTUAL PHYSICAL
602010 2a683010
PML: 36df9000 => 3a654067
PUD: 3a654000 => 1a71a067
PMD: 1a71a018 => 18f2a067
PTE: 18f2a010 => 800000002a683065
PAGE: 2a683000
我的问题是cpu执行时发生了什么
movl $0x2c,-0x20(%rbp)
内核如何知道它正在更改共享内存,因此在写入之前需要执行应对?我猜它正在使用诸如页面错误中断之类的东西。但我没有发现任何与此相关的中断。
如果内核负责,请提供内核源代码。
【问题讨论】:
-
如果内核负责,请提供内核源代码。 github.com/torvalds/linux
-
@AndrewHenle 不错 :-)
-
我觉得这个比github好code.woboq.org/linux/linux
标签: c linux linux-kernel copy-on-write