I'm having a very tough time debugging a multi-threaded C application that I've made a few changes to. I've been unable to use GDB to help identify the issue(see below code for more info).
The following code is from one of the tasks that is opened in its own thread. I've snipped out most of the code following the problem.
void tskProcessTenMinuteTables(void *input)
{
/* Check the minute as soon as we start. If we're started on a ten min
* boundary, sleep for one minute.
*/
time_t now;
time_t wakeup;
struct tm *next_tick_ptr;
now = time(NULL);
next_tick_ptr = localtime(&now);
/* returns a time struct populated w/ next ten min boundary */
GetNextTenMinBoundary(next_tick_ptr);
wakeup = mktime(next_tick_ptr);
sleep(2); /* Without this sleep, the following if() was always true. */
if(next_tick_ptr->tm_min % 10 == 0)
{
fprintf(stderr, "On tenmin boundary on initialization.. task sleeping for 60 seconds.\n");
/* debug statements to test the cause of segfault. */
fprintf(stderr, "NOM NOM NOM\n");
printf( "Test%d\n", 1);
fprintf(stderr, "Test%d\n", 2); /* <~~~ This statement is the guilty party */
sleep(60);
}
/* Main loop. Every loop besides the tick itself will consist only
* of a call to time and a comparison of current stamp with wakeup.
* this should be pretty light on the processing side.
*
* Re-implement this as a sleep/awake with a signal in the future.
*/
while(1)
{
now = time(NULL);
if( now >= wakeup )
{
fprintf(stderr, "Triggered 1.\n");
fprintf(stderr, "Triggered 2.\n");
char statement[150];
fprintf(stderr, "Triggered 3.\n");
sprintf(statement, "SELECT ten_min_end(%d::int2)",GetTenMinPeriodNumber());
fprintf(stderr, "Triggered 4.\n");
DBCallStoredProcedure(statement);
fprintf(stderr, "Triggered 5.\n");
}
}
The cause is attempting to use fprintf with variadic(?) args. Calling it without anything besides the pattern works. Printf functions with or without args.
fprintf(stderr, "Hi #%d.\n", 1); <~~ segfault
fprintf(stderr, "Hi #1.\n"); <~~ works
printf("Hi #%d.\n", 1); <~~ works
printf("Hi #1.\n"); <~~ works
When run in gdb, I receive the following spewage before gdb becomes unresponsive. A kill -9 is needed to terminate.
$gdb ir_client
(gdb) r
Starting program: /home/ziop/Experimental_IR_Clients/ir-10-20/IR_Client/obj-linux-x86/ir_client
[Thread debugging using libthread_db enabled]
[New Thread 0xb7fe5b70 (LWP 32269)]
[New Thread 0xb7fc4b70 (LWP 32270)]
(032266 - -1208067216) 20-Oct-2010 10:56:19.59 - IR_Client_ConnectCmdPort - Socket connected.
[New Thread 0xb7ffdb70 (LWP 32272)]
(032266 - main thread) 20-Oct-2010 10:56:19.59 - sl_exit - Exiting thread with code 0.
On tenmin boundary on initialization.. task sleeping for 60 seconds.
NOM NOM NOM
Test1
I'm fairly new at C, so it may be something obvious. My first thought was something with the unbuffered output was not thread-safe but the fprintf always succeeds if no variable is passed. Pthread funkiness is still my top suspect. Unfortunately I'm stuck with the architecture for the time being.
Thanks in advance.