Dtruss 没有显示 mmap/sbrk 个调用?
Dtruss not showing mmap/sbrk calls?
我最近决定学习更多关于系统编程的知识,并且觉得了解我的代码实际在做什么会很有帮助。
为此,我用 C++ 编写了一个简短的 LinkedList class 并决定使用 dtruss
(阅读:dtrace)对其进行跟踪。
我的期望是任何扩展堆的指令(例如使用 new
关键字,或实例化 LinkedList 对象)将调用 mmap
或 sbrk
/break
系统调用。事实并非如此!
事实上,运行 dtruss
使用 -s 开关,我没有看到 任何 系统调用从我的 LinkedList::Add
功能!正在测试,我确定正在添加某些元素。
谁能解释为什么我在 dtruss 输出中看不到对 mmap
/sbrk
的引用?
如果有人能解释 mprotect
和 madvise
的目的,加分。
我在下面包含了我的 LinkedList class、main.cpp 和 dtruss 输出。
谢谢!
dtruss 输出
SYSCALL(args) = return
Created new LinkedList
Created new LinkedList
Destroyed a LinkedList
open("/dev/dtracehelper[=11=]", 0x2, 0xFFFFFFFFE3236D70) = 3 0
ioctl(0x3, 0x80086804, 0x7FFEE3236CD0) = 0 0
close(0x3) = 0 0
access("/AppleInternal/XBS/.isChrooted[=11=]", 0x0, 0x0) = -1 Err#2
thread_selfid(0x0, 0x0, 0x0) = 198178 0
bsdthread_register(0x7FFF5BAB5C50, 0x7FFF5BAB5C40, 0x2000) = 1073742047 0
issetugid(0x0, 0x0, 0x0) = 0 0
mprotect(0x10C9D0000, 0x1000, 0x0) = 0 0
mprotect(0x10C9D5000, 0x1000, 0x0) = 0 0
mprotect(0x10C9D6000, 0x1000, 0x0) = 0 0
mprotect(0x10C9DB000, 0x1000, 0x0) = 0 0
mprotect(0x10C9CE000, 0x88, 0x1) = 0 0
mprotect(0x10C9DC000, 0x1000, 0x1) = 0 0
mprotect(0x10C9CE000, 0x88, 0x3) = 0 0
mprotect(0x10C9CE000, 0x88, 0x1) = 0 0
getpid(0x0, 0x0, 0x0) = 1698 0
stat64("/AppleInternal/XBS/.isChrooted[=11=]", 0x7FFEE32362E8, 0x0) = -1 Err#2
stat64("/AppleInternal[=11=]", 0x7FFEE3236380, 0x0) = -1 Err#2
csops(0x6A2, 0x7, 0x7FFEE3235E20) = -1 Err#22
sysctl([CTL_KERN, 14, 1, 1698, 0, 0] (4), 0x7FFEE3235F68, 0x7FFEE3235F60, 0x0, 0x0) = 0 0
csops(0x6A2, 0x7, 0x7FFEE3235710) = -1 Err#22
getrlimit(0x1008, 0x7FFEE32374F0, 0x0) = 0 0
fstat64(0x1, 0x7FFEE3237508, 0x0) = 0 0
ioctl(0x1, 0x4004667A, 0x7FFEE3237554) = 0 0
write_nocancel(0x1, "Created new LinkedList\n[=11=]", 0x17) = 23 0
write_nocancel(0x1, "Created new LinkedList\n[=11=]", 0x17) = 23 0
write_nocancel(0x1, "Destroyed a LinkedList\n[=11=]", 0x17) = 23 0
LinkedList.cpp
#include <iostream>
#include "LinkedList.h"
using namespace std;
LinkedList::LinkedList() {
this->length = 0;
this->head = NULL;
this->tail = NULL;
cout << "Created new LinkedList" << endl;
}
LinkedList::~LinkedList() {
Node* curr;
Node* temp;
curr = this->head;
while ( curr ) {
temp = curr;
curr = curr->next;
delete temp;
}
cout << "Destroyed a LinkedList" << endl;
}
void LinkedList::Add(int v) {
Node* n = new Node();
n->val = v;
n->next = NULL;
if (!this->head) {
this->head = n;
this->tail = n;
} else {
this->tail->next = n;
this->tail = n;
}
}
main.cpp
#include <iostream>
#include "LinkedList.h"
using namespace std;
int main() {
LinkedList l; // You should require a heap increase, right?
LinkedList* ll = new LinkedList(); // Surely you require more heap!
for (int i=0; i<1000; i++)
l.Add(i);
return 0;
}
我发现 Mac OS 不像大多数 UNIX/Linuxes 那样使用 sbrk/brk/break()
进行内存管理。基本上,它使用的是 Apple 从 NeXT 继承的 Mach 内核,因此内存调用将是 mpadvise(2)
和 mprotect(2)
,它们提供比 sbrk()
.[=] 更精细的粒度控制。 23=]
来自乔纳森·莱文的 "Mac OS X and iOS Internals":
因此,要解释您的内存分配,您需要了解 sys/mman.h
header.
中的 mprotect(2)
参数
#define PROT_NONE 0x00 /* [MC2] no permissions */
#define PROT_READ 0x01 /* [MC2] pages can be read */
#define PROT_WRITE 0x02 /* [MC2] pages can be written */
#define PROT_EXEC 0x04 /* [MC2] pages can be executed */
....
因此您的系统调用将意味着:
mprotect(0x10C9D0000, 0x1000, 0x0) = 0 0
mprotect(0x10C9D5000, 0x1000, 0x0) = 0 0
mprotect(0x10C9D6000, 0x1000, 0x0) = 0 0
mprotect(0x10C9DB000, 0x1000, 0x0) = 0 0
mprotect(0x10C9CE000, 0x88, 0x1) = 0 0 <-- Allow reads starting at 0x10C9CE000 for 136 bytes
mprotect(0x10C9DC000, 0x1000, 0x1) = 0 0
mprotect(0x10C9CE000, 0x88, 0x3) = 0 0 <-- Allow reads and writes starting at 0x10C9CE000 for 136 bytes
mprotect(0x10C9CE000, 0x88, 0x1) = 0 0
关于 mmap(2)
,在 Linux 系统上,它用于映射共享库的 object 代码,但不用于 malloc/free
或 new/delete
。
参考文献:
- 白皮书 异构内存的用户可扩展堆管理器
平台和混合内存策略
- Mac OS X and iOS Internals
- "Mac OS X Internals: A Systems Approach" 阿米特·辛格
我最近决定学习更多关于系统编程的知识,并且觉得了解我的代码实际在做什么会很有帮助。
为此,我用 C++ 编写了一个简短的 LinkedList class 并决定使用 dtruss
(阅读:dtrace)对其进行跟踪。
我的期望是任何扩展堆的指令(例如使用 new
关键字,或实例化 LinkedList 对象)将调用 mmap
或 sbrk
/break
系统调用。事实并非如此!
事实上,运行 dtruss
使用 -s 开关,我没有看到 任何 系统调用从我的 LinkedList::Add
功能!正在测试,我确定正在添加某些元素。
谁能解释为什么我在 dtruss 输出中看不到对 mmap
/sbrk
的引用?
如果有人能解释 mprotect
和 madvise
的目的,加分。
我在下面包含了我的 LinkedList class、main.cpp 和 dtruss 输出。
谢谢!
dtruss 输出
SYSCALL(args) = return
Created new LinkedList
Created new LinkedList
Destroyed a LinkedList
open("/dev/dtracehelper[=11=]", 0x2, 0xFFFFFFFFE3236D70) = 3 0
ioctl(0x3, 0x80086804, 0x7FFEE3236CD0) = 0 0
close(0x3) = 0 0
access("/AppleInternal/XBS/.isChrooted[=11=]", 0x0, 0x0) = -1 Err#2
thread_selfid(0x0, 0x0, 0x0) = 198178 0
bsdthread_register(0x7FFF5BAB5C50, 0x7FFF5BAB5C40, 0x2000) = 1073742047 0
issetugid(0x0, 0x0, 0x0) = 0 0
mprotect(0x10C9D0000, 0x1000, 0x0) = 0 0
mprotect(0x10C9D5000, 0x1000, 0x0) = 0 0
mprotect(0x10C9D6000, 0x1000, 0x0) = 0 0
mprotect(0x10C9DB000, 0x1000, 0x0) = 0 0
mprotect(0x10C9CE000, 0x88, 0x1) = 0 0
mprotect(0x10C9DC000, 0x1000, 0x1) = 0 0
mprotect(0x10C9CE000, 0x88, 0x3) = 0 0
mprotect(0x10C9CE000, 0x88, 0x1) = 0 0
getpid(0x0, 0x0, 0x0) = 1698 0
stat64("/AppleInternal/XBS/.isChrooted[=11=]", 0x7FFEE32362E8, 0x0) = -1 Err#2
stat64("/AppleInternal[=11=]", 0x7FFEE3236380, 0x0) = -1 Err#2
csops(0x6A2, 0x7, 0x7FFEE3235E20) = -1 Err#22
sysctl([CTL_KERN, 14, 1, 1698, 0, 0] (4), 0x7FFEE3235F68, 0x7FFEE3235F60, 0x0, 0x0) = 0 0
csops(0x6A2, 0x7, 0x7FFEE3235710) = -1 Err#22
getrlimit(0x1008, 0x7FFEE32374F0, 0x0) = 0 0
fstat64(0x1, 0x7FFEE3237508, 0x0) = 0 0
ioctl(0x1, 0x4004667A, 0x7FFEE3237554) = 0 0
write_nocancel(0x1, "Created new LinkedList\n[=11=]", 0x17) = 23 0
write_nocancel(0x1, "Created new LinkedList\n[=11=]", 0x17) = 23 0
write_nocancel(0x1, "Destroyed a LinkedList\n[=11=]", 0x17) = 23 0
LinkedList.cpp
#include <iostream>
#include "LinkedList.h"
using namespace std;
LinkedList::LinkedList() {
this->length = 0;
this->head = NULL;
this->tail = NULL;
cout << "Created new LinkedList" << endl;
}
LinkedList::~LinkedList() {
Node* curr;
Node* temp;
curr = this->head;
while ( curr ) {
temp = curr;
curr = curr->next;
delete temp;
}
cout << "Destroyed a LinkedList" << endl;
}
void LinkedList::Add(int v) {
Node* n = new Node();
n->val = v;
n->next = NULL;
if (!this->head) {
this->head = n;
this->tail = n;
} else {
this->tail->next = n;
this->tail = n;
}
}
main.cpp
#include <iostream>
#include "LinkedList.h"
using namespace std;
int main() {
LinkedList l; // You should require a heap increase, right?
LinkedList* ll = new LinkedList(); // Surely you require more heap!
for (int i=0; i<1000; i++)
l.Add(i);
return 0;
}
我发现 Mac OS 不像大多数 UNIX/Linuxes 那样使用 sbrk/brk/break()
进行内存管理。基本上,它使用的是 Apple 从 NeXT 继承的 Mach 内核,因此内存调用将是 mpadvise(2)
和 mprotect(2)
,它们提供比 sbrk()
.[=] 更精细的粒度控制。 23=]
来自乔纳森·莱文的 "Mac OS X and iOS Internals":
因此,要解释您的内存分配,您需要了解 sys/mman.h
header.
mprotect(2)
参数
#define PROT_NONE 0x00 /* [MC2] no permissions */
#define PROT_READ 0x01 /* [MC2] pages can be read */
#define PROT_WRITE 0x02 /* [MC2] pages can be written */
#define PROT_EXEC 0x04 /* [MC2] pages can be executed */
....
因此您的系统调用将意味着:
mprotect(0x10C9D0000, 0x1000, 0x0) = 0 0
mprotect(0x10C9D5000, 0x1000, 0x0) = 0 0
mprotect(0x10C9D6000, 0x1000, 0x0) = 0 0
mprotect(0x10C9DB000, 0x1000, 0x0) = 0 0
mprotect(0x10C9CE000, 0x88, 0x1) = 0 0 <-- Allow reads starting at 0x10C9CE000 for 136 bytes
mprotect(0x10C9DC000, 0x1000, 0x1) = 0 0
mprotect(0x10C9CE000, 0x88, 0x3) = 0 0 <-- Allow reads and writes starting at 0x10C9CE000 for 136 bytes
mprotect(0x10C9CE000, 0x88, 0x1) = 0 0
关于 mmap(2)
,在 Linux 系统上,它用于映射共享库的 object 代码,但不用于 malloc/free
或 new/delete
。
参考文献:
- 白皮书 异构内存的用户可扩展堆管理器 平台和混合内存策略
- Mac OS X and iOS Internals
- "Mac OS X Internals: A Systems Approach" 阿米特·辛格