X-Recipient: archive-cygwin AT delorie DOT com X-SWARE-Spam-Status: No, hits=-1.4 required=5.0 tests=AWL,BAYES_00,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-class: urn:content-classes:message Subject: Unfolding the stack Date: Mon, 12 Mar 2012 10:39:05 +0100 Message-ID: <6BFA9AF2C7556E42AFF3F187ECAB07B802DAFBAB@bespdc01.mediaxim.local> From: "Michel Bardiaux" To: X-IsSubscribed: yes Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by delorie.com id q2C9duaX020164 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