Ich habe große Schwierigkeiten beim Debuggen einer mehrfädigen C-Anwendung, die ich ein paar Änderungen vorgenommen habe. Ich konnte GDB nicht verwenden, um das Problem zu identifizieren(siehe untenstehenden Code für weitere Informationen).
Der folgende Code stammt von einer der Aufgaben, die in einem eigenen Thread geöffnet ist. Ich habe den größten Teil des Codes nach dem Problem entfernt.
void tskProcessTenMinuteTables(void *input)
{
/* Überprüfen der Minute sofort nach dem Start. Wenn wir auf einer Zehnminuten-Grenze gestartet haben, schlafen wir eine Minute.
*/
time_t now;
time_t wakeup;
struct tm *next_tick_ptr;
now = time(NULL);
next_tick_ptr = localtime(&now);
/* gibt eine mit dem nächsten Zehnminutenzeitstempel gefüllte Zeitstruktur zurück */
GetNextTenMinBoundary(next_tick_ptr);
wakeup = mktime(next_tick_ptr);
sleep(2); /* Ohne diesen Schlaf war das folgende if() immer wahr. */
if(next_tick_ptr->tm_min % 10 == 0)
{
fprintf(stderr, "Auf Zehnminuten-Grenze bei Initialisierung.. Aufgabe schläft für 60 Sekunden.\n");
/* Debug-Meldungen zum Testen der Ursache des Segfaults. */
fprintf(stderr, "NOM NOM NOM\n");
printf( "Test%d\n", 1);
fprintf(stderr, "Test%d\n", 2); /* <~~~ Diese Anweisung ist der Übeltäter */
sleep(60);
}
/* Hauptschleife. Jede Schleifenrunde außer dem Tick selbst besteht nur aus einem Aufruf von time und einem Vergleich des aktuellen Stempels mit dem Aufwachen.
* das sollte ziemlich leicht auf der Verarbeitungsseite sein.
*
* Implementieren Sie dies neu als Schlafen/Aufwachen mit einem Signal in der Zukunft.
*/
while(1)
{
now = time(NULL);
if( now >= wakeup )
{
fprintf(stderr, "Ausgelöst 1.\n");
fprintf(stderr, "Ausgelöst 2.\n");
char statement[150];
fprintf(stderr, "Ausgelöst 3.\n");
sprintf(statement, "SELECT ten_min_end(%d::int2)",GetTenMinPeriodNumber());
fprintf(stderr, "Ausgelöst 4.\n");
DBCallStoredProcedure(statement);
fprintf(stderr, "Ausgelöst 5.\n");
}
}
Die Ursache liegt im Versuch, fprintf mit variadischen(?)-Argumenten zu verwenden. Wenn man es nur mit dem Muster aufruft, funktioniert es. Printf funktioniert mit oder ohne Argumente.
fprintf(stderr, "Hi #%d.\n", 1); <~~ segfault
fprintf(stderr, "Hi #1.\n"); <~~ funktioniert
printf("Hi #%d.\n", 1); <~~ funktioniert
printf("Hi #1.\n"); <~~ funktioniert
Beim Ausführen in gdb erhalte ich die folgende Ausgabe, bevor gdb nicht mehr reagiert. Ein kill -9 ist erforderlich, um zu beenden.
$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 - Hauptthread) 20-Oct-2010 10:56:19.59 - sl_exit - Thread wird mit Code 0 beendet.
Auf Zehnminuten-Grenze bei Initialisierung.. Aufgabe schläft für 60 Sekunden.
NOM NOM NOM
Test1
Ich bin noch ziemlich neu in C, daher kann es etwas Offensichtliches sein. Mein erster Gedanke war, dass etwas mit der nicht-gepufferten Ausgabe nicht threadsicher ist, aber fprintf gelingt immer, wenn außer dem Muster nichts übergeben wird. Pthread-Seltsamkeiten sind immer noch mein Hauptverdächtiger. Leider bin ich vorerst auf die Architektur beschränkt.
Vielen Dank im Voraus.