I'm writing a program that's examining its own address space.
Specifically, I care about all malloc-ed data blocks. If there some system call to get a list of them, that would be fantastic (for my application, I cannot use LD_PRELOAD, -wrap, nor any extra command line options). If there's a way to do this, I'd love to hear it even more than an answer to my stated problem, below.
In lieu of this, my current approach is to just dereference everything and look around. Obviously, the set of all possible pointers is a minefield of segfaults waiting to happen, so I tried registering a signal handler and using setjmp/longjmp (simply ignoring the segfault by making the handler do nothing is an infinite loop because the handler will return to the faulting instruction). Some example code goes like so:
static jmp_buf buf;
void handler(int i) {
printf(" Segfaulted!\n");
longjmp(buf,-1);
}
void segfault(void) {
int* x = 0x0;
int y = *x;
}
void test_function(void) {
signal(11,handler);
while (1) {
if (setjmp(buf)==0) {
printf("Segfaulting:\n");
segfault();
}
else {
printf("Recovered and not segfaulting!\n");
}
printf("\n");
}
}
The output is:
Segfaulting:
Segfaulted!
Recovered and not segfaulting!
Segfaulting:
Segmentation fault
So, the handler didn't work the second time around. I don't know why this is, but I speculated it had something to do with not clearing the original signal. I don't know how to do that.
As an aside, I tried sigsetjmp/siglongjmp first, but they weren't defined for some reason in setjmp.h. I got vague vibes that one needed to pass some extra compile flags, but, as before, that is not allowed for this application.
The system being used is Ubuntu Linux 10.04 x86-64, and any solution does not need to be portable.
[EDIT: sigrelse in the handler clears the signal, and fixes the problem effectively. Question now concerns the other issues raised--is there a better way (i.e., get the blocks of malloc)? What's up with sigsetjmp/siglongjmp? Why do I need to reset the signal?]