This first patch fixes a seg-fault at `make test' time -- profile.test crashes without this change. Submitted to maintainers: https://sourceforge.net/tracker/index.php?func=detail&aid=1925400&group_id=13247&atid=113247 and committed upstream. The second changes TclXOSElapsedTime to better handles clock_t being too narrow (32-bit on FreeBSD). Getting it committed upstream... -mi --- generic/tclXprofile.c 2004-11-22 19:12:54.000000000 -0500 +++ generic/tclXprofile.c 2009-07-31 02:44:11.000000000 -0400 @@ -674,5 +674,5 @@ CallFrame *framePtr; { - if (framePtr == NULL) + if (framePtr == NULL || framePtr->objv == NULL) return; InitializeProcStack (infoPtr, framePtr->callerPtr); --- unix/tclXunixOS.c 2005-07-12 15:03:15.000000000 -0400 +++ unix/tclXunixOS.c 2009-11-27 02:00:57.000000000 -0500 @@ -550,4 +550,10 @@ * o realTime - Elapsed real time, in milliseconds is returned here. * o cpuTime - Elapsed CPU time, in milliseconds is returned here. + * + * XXX In some cases, clock_t may not be wide enough, such as when it is + * XXX a signed 32-bit value, its maximum is 2^31 or 2147483648. There + * XXX are more milliseconds in 25 days: 25*1000*60*60*24 = 2160000000. + * XXX If a profile-session is to last longer than that, the API needs + * XXX to use 64-bit values. -mi Nov 27, 2009 *----------------------------------------------------------------------------- */ @@ -557,4 +563,5 @@ clock_t *cpuTime; { + struct tms cpuTimes; /* * If times returns elapsed real time, this is easy. If it returns a status, @@ -562,25 +569,34 @@ */ #ifndef TIMES_RETS_STATUS - struct tms cpuTimes; + static clock_t startTime; + clock_t currentTime; - *realTime = TclXOSTicksToMS (times (&cpuTimes)); - *cpuTime = TclXOSTicksToMS (cpuTimes.tms_utime + cpuTimes.tms_stime); + /* + * If this is the first call, get base time. + */ + currentTime = times (&cpuTimes); + if (startTime == 0) { + startTime = currentTime; + *realTime = 0; + } else + *realTime = TclXOSTicksToMS (currentTime - startTime); #else static struct timeval startTime = {0, 0}; struct timeval currentTime; - struct tms cpuTimes; /* * If this is the first call, get base time. */ - if ((startTime.tv_sec == 0) && (startTime.tv_usec == 0)) + if ((startTime.tv_sec == 0) && (startTime.tv_usec == 0)) { gettimeofday (&startTime, NULL); - - gettimeofday (¤tTime, NULL); - currentTime.tv_sec = currentTime.tv_sec - startTime.tv_sec; - currentTime.tv_usec = currentTime.tv_usec - startTime.tv_usec; - *realTime = (currentTime.tv_sec * 1000) + (currentTime.tv_usec / 1000); + *realTime = 0; + } else { + gettimeofday (¤tTime, NULL); + currentTime.tv_sec = currentTime.tv_sec - startTime.tv_sec; + currentTime.tv_usec = currentTime.tv_usec - startTime.tv_usec; + *realTime = (currentTime.tv_sec * 1000) + (currentTime.tv_usec / 1000); + } times (&cpuTimes); - *cpuTime = TclXOSTicksToMS (cpuTimes.tms_utime + cpuTimes.tms_stime); #endif + *cpuTime = TclXOSTicksToMS (cpuTimes.tms_utime + cpuTimes.tms_stime); } --- unix/tclXunixPort.h 2005-10-07 19:30:28.000000000 -0400 +++ unix/tclXunixPort.h 2009-11-27 02:31:15.000000000 -0500 @@ -66,4 +66,10 @@ * Make sure CLK_TCK is defined. */ +#ifdef __FreeBSD__ +# if defined(CLK_TCK) && CLK_TCK == 128 +# undef CLK_TCK +# define CLK_TCK sysconf(_SC_CLK_TCK) +# endif +#endif #ifndef CLK_TCK # ifdef HZ