我正在使用以下代码检查学生作业。返回堆栈内存是一个常见的陷阱,所以我想自动检查它。
使用sbrk
此方法应适用于所有 Unix 变体和所有 CPU 架构。
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
bool points_to_heap(void* init_brk, void* pointer){
void* cur_brk = sbrk(0);
return ((init_brk <= pointer) && (pointer <= cur_brk));
}
int main(void){
void* init_brk = sbrk(0);
int* heapvar = malloc(10);
int i = 0;
int* stackvar = &i;
assert(points_to_heap(init_brk, heapvar));
assert(!points_to_heap(init_brk, stackvar));
return 0;
}
使用/proc/self/maps
这种方法有两个问题:
- 此代码特定于在 64 位 x86 CPU 上运行的 Linux。
- 此方法似乎不适用于使用
libcheck
框架编写的单元测试。在那里,所有堆栈变量也被视为堆变量。
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
void get_heap_bounds(uint64_t* heap_start, uint64_t* heap_end){
FILE *stream;
char *line = NULL;
size_t len = 0;
ssize_t nread;
stream = fopen("/proc/self/maps", "r");
while ((nread = getline(&line, &len, stream)) != -1) {
if (strstr(line, "[heap]")){
sscanf(line, "%" SCNx64 "-%" SCNx64 "", heap_start, heap_end);
break;
}
}
free(line);
fclose(stream);
}
bool is_heap_var(void* pointer){
uint64_t heap_start = 0;
uint64_t heap_end = 0;
get_heap_bounds(&heap_start, &heap_end);
if (pointer >= (void*)heap_start && pointer <= (void*)heap_end){
return true;
}
return false;
}
欢迎对此代码提供反馈!