我有这个代码:
static void XMLCALL
hackHandler(void *data, const XML_Char *name, const XML_Char **attr)
{
SetPointers* sets = static_cast<SetPointers*>(data);
if (strcmp(name, "instruction") == 0 || strcmp(name, "load") == 0 ||
strcmp(name, "modify") == 0||strcmp(name, "store") == 0) {
long address(0);
long page(0);
int offset(0);
long size(0);
int i(0);
for (i = 0; attr[i]; i += 2) {
if (strcmp(attr[i], "address") == 0) {
address = strtol(attr[i+1], NULL, 16);
page = address >> 12;
offset = address & 0xFFF;
continue;
}
if (strcmp(attr[i], "size") == 0) {
size = strtol(attr[i + 1], NULL, 16);
}
}
map<long, bitset<4096> >::iterator itLocal;
itLocal = sets->lCount->find(page);
if (itLocal == sets->lCount->end()) {
sets->lCount->insert(pair<long, bitset<4096> >
(page, bitset<4096>()));
itLocal = sets->lCount->find(page);
}
//now mark the bitmap
for (i = 0; i < size; i++) {
(itLocal->second)[i + offset] = 1;
}
if (strcmp(name, "instruction") == 0) {
itLocal = sets->lCode->find(page);
if (itLocal == sets->lCode->end()) {
sets->lCode->insert(pair<long, bitset<4096> >
(page, bitset<4096>()));
itLocal = sets->lCode->find(page);
}
for (i = 0; i < size; i++) {
(itLocal->second)[i + offset] = 1;
}
} else {
itLocal = sets->lMemory->find(page);
if (itLocal == sets->lMemory->end()) {
sets->lMemory->insert(pair<long, bitset<4096> >
(page, bitset<4096>()));
itLocal = sets->lMemory->find(page);
}
for (i = 0; i < size; i++) {
(itLocal->second)[i + offset] = 1;
}
}
}
}
这旨在在访问页面的该字节时用 1 标记一个 4096 位长的位集。
当我使用大约 1GB 的 XML 进行测试时,这段代码在我的测试机器上运行良好。但是当我在完整的东西(220GB 的 XML)上运行它时,它会出现以下分段错误:
sets->lCode->insert(pair<long, bitset<4096> >
(page, bitset<4096>()));
但是它在运行的早期就这样做了,所以很难认为这是数据大小的产物。无论如何,我在使用一些非常相似的代码分析这个更大的数据集时没有问题(在https://github.com/mcmenaminadrian上查看我的 github 存储库- 这个项目是 memsize,但 pagestat 使用非常相似的代码)。此代码的唯一区别因素似乎是位集的使用。
有人能发现到目前为止我一直没有发现的错误吗?
(代码是多线程的 - bitset 线程安全吗?这可能是库问题 - 我的测试系统是 Mac OSX,但“生产”系统是 Linux - Ubuntu 12.04 LTS?)