Mail Archives: cygwin/2012/03/12/05:40:01
To complete the port of some library to Cygwin, I need a way to produce
a traceback with as much info as possible. Currently I have something
that works but not that well. There are basically 3 parts:
* Gather all the stack frames; see below.
* Assign the PCs in each frame to some executable image; done via dlfcn.
To be discussed later.
* Convert the PCs to function+source+line; done via addr2line. Ditto.
Despite a lot of web digging I have not (yet?) found a better way than
this classic unixish song-and-dance:
int
backtrace(void** buf, int bufsiz)
{
int res;
int p[2];
pid_t child;
FILE* thePipe = (NULL);
char line[1024];
void* unused;
if (pipe(p) < 0){
debug(-1, "*** Pipe() failed\n");
return -1;
}
if ((child=fork())<0) {
debug(-1, "*** Fork() failed\n");
return -1;
} else if (child == 0) {
// In child. Make p[1] its stderr
close(0);
close(1);
dup2 (p[1], 2);
close (p[0]);
close (p[1]);
cygwin_stackdump();
exit(0);
}
// In our process. Read from the pipe.
close (p[1]);
if((thePipe=fdopen(p[0], "rb"))==NULL) {
debug(-1, "*** fdopen failed\n");
return -1;
}
res = 0;
while(fgets(line, sizeof(line), thePipe)) {
if(res>=bufsiz)
break;
while(isspace(line[strlen(line)-1]))
line[strlen(line)-1]=0;
if(strcmp(line, "Stack trace:")==0 ||
strncmp(line, "Frame", 5)==0)
continue;
if(strcmp(line, "End of stack trace")==0)
break;
if(sscanf(line, "%8X %8X", (int*)&unused,
(int*)(buf+res))!=2) {
debug(-1, "*** sscanf failed\n");
return -1;
}
res++;
}
fclose(thePipe);
return res;
}
Where debug(-1,...) is essentially fprintf(stderr,...).
Now this is acceptable for a traceback following the raising of some
error condition, but seems much too heavy for using in a leak detector.
Does anyone know of an equivalent API under cygwin? Or could we consider
adding such a variation of cygwin_stackdump to the cygwin DLL?
TiA
Michel Bardiaux
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
- Raw text -