Forum: PC-Programmierung Standardausgabe funktioniert nicht -mehr-


von Matthias (Gast)


Lesenswert?

Ich habe ein C-Programm, welches im Verlauf seiner Abarbeitung immer 
wieder einfache Debugmeldungen via printf() ausgibt.

Wird die nachfolgende Stelle im Programmcode erreicht, werden zwar noch 
die hierin enthaltenen Ausgaben ueber die Standardausgabe vorgenommen, 
dann aber war es das.

Setze ich nach diesem Codeabschnitt eine printf() Funktion, gibt diese 
nichts mehr zurueck.

Das Programm läuft ohne Warnungen und Fehlermeldungen durch den 
Compiler.
1
if((status = getaddrinfo (url, NULL, &hints, &res)) != 0){
2
    fprintf (stderr, "getaddrinfo() failed: %s\n", gai_strerror (status));
3
  }
4
  else{
5
    printf("getaddrinfo() succeeded...\n");
6
    printf("ZielURL %s\n", URL_STRING);
7
    for(a = 1, res_loop = res; res_loop != NULL; a++ ,res_loop = res_loop->ai_next){  
8
      my_sin_addr = (struct sockaddr_in *)res_loop->ai_addr;
9
      printf("IP[%d]: %s\n",a , inet_ntoa(my_sin_addr->sin_addr));
10
    }
11
  }

von John (Gast)


Lesenswert?

Wird die for Schleife korrekt beendet?

von Matthias (Gast)


Lesenswert?

Ich habe es mit verschiedenen URLs ausprobiert und jedesmal kommt eine 
saubere Liste mit den entsprechenden IPs.

Ja, würde ich sagen.

von Dirk B. (dirkb2)


Lesenswert?

Matthias schrieb:
> Ich habe es mit verschiedenen URLs ausprobiert und jedesmal kommt eine
> saubere Liste mit den entsprechenden IPs.
>
> Ja, würde ich sagen.

Wie stellst du fest, dass sich die Schleife nicht bei  inet_ntoa 
aufhängt?
1
    for(a = 1, res_loop = res; res_loop != NULL; a++ ,res_loop = res_loop->ai_next){  
2
      my_sin_addr = (struct sockaddr_in *)res_loop->ai_addr;
3
      printf("IP[%d]: ", a); fflush(stdout);
4
      printf("%s", inet_ntoa(my_sin_addr->sin_addr)); fflush(stdout);
5
      puts(" (ok)"); fflush(stdout);
6
    }

von Manfred M. (bittbeisser)


Lesenswert?

Ich benutze in für debugging Zwecke immer
1
  fprintf( stderr, "..." );
das ist immer ungepuffert.

von Matthias (Gast)


Lesenswert?

Danke für die Rückmeldungen.

@Dirk
Was ich nicht verstehe ist die Frage nach dem Warum. Wieso sollte ich 
das flushen?

Die zweite Frage, welche ich mir stelle, wieso erhalte ich, wenn es denn 
nötig wäre, keinerlei Rueckmeldungen seitens des Compilers?

Mein derzeitiges Programm ist noch relativ ueberschaubar. Was mache ich, 
wenn ich tausende Code-Zeilen habe und der gleiche Fehler auftritt? -und 
der Compiler alles so durchwinkt?

von Rolf M. (rmagnus)


Lesenswert?

Matthias schrieb:
> Danke für die Rückmeldungen.
>
> @Dirk
> Was ich nicht verstehe ist die Frage nach dem Warum. Wieso sollte ich
> das flushen?

Brauchst du nicht. Bei Dirk fehlen die Zeilenumbrüche, da braucht man 
ein explizite Flush, um die Daten rauzuschicken.

> Die zweite Frage, welche ich mir stelle, wieso erhalte ich, wenn es denn
> nötig wäre, keinerlei Rueckmeldungen seitens des Compilers?

Rückmeldung zu was?

> Mein derzeitiges Programm ist noch relativ ueberschaubar. Was mache ich,
> wenn ich tausende Code-Zeilen habe und der gleiche Fehler auftritt?

Du teilst dein Programm in überschaubare eineln testbare Module auf. 
Wenn das nur ein großer Klumpen ist, bei dem alles kreuz und quer läuft, 
wird's natürlich schwierig.

von Matthias (Gast)


Lesenswert?

@Rolf Magnus

> Rückmeldung zu was?

Genau das frage ich mich ja. Ich weiß nicht, wo im obigen Code ein 
Fehler sein soll.

Ich bin schon dabei zu modularisieren und meinen Code in Bibliotheken 
auszulagern.

Mir ging es um die Frage, wieso die Standardausgabe ploetzlich nichts 
mehr rueckmeldet. Aufgrund von Dirks Antwort bin ich von einem Fehler im 
Code ausgegangen, den ich aber nicht finden kann.

Davon mal abgesehen, wenn das Phaenomen auftritt, das STDOUT nicht mehr 
laeuft, wieso meldet sich dann der Compiler nicht?

Bis zum obigen Codestueck lauft alles reibungslos, danach herrscht 
Stille. Mir ist nicht klar, wieso sich der Schleifenteil aufhaengen 
koennte.

von siggi (Gast)


Lesenswert?

Matthias schrieb:
> Die zweite Frage, welche ich mir stelle, wieso erhalte ich, wenn es denn
> nötig wäre, keinerlei Rueckmeldungen seitens des Compilers?

Der Compiler ist kein Debugger.

von Dirk B. (dirkb2)


Lesenswert?

Matthias schrieb:
> Bis zum obigen Codestueck lauft alles reibungslos, danach herrscht
> Stille. Mir ist nicht klar, wieso sich der Schleifenteil aufhaengen
> koennte.

Ich habe die Ausgabe in drei Teile aufgeteilt. Wenn du in der Letzten 
Ausgabe kein (ok) in der Zeile steht, hängt das Programm bei inet_ntoa

Das flush wird benötigt, damit die bisher geschriebenen Zeichen auch 
(vor dem Absturz) ausgegeben werden.

Das ist nur Testcode.

von mar IO (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Brauchst du nicht. Bei Dirk fehlen die Zeilenumbrüche, da braucht man
> ein explizite Flush, um die Daten rauzuschicken.

Da hat der Rolf recht. Kurz recherchiert, aber es war so, dass stdout 
"line buffered" ist. Daneben gibt es noch unbuffered (z.B. stderr) und 
full buffered.

siggi schrieb:
> Matthias schrieb:
>> Die zweite Frage, welche ich mir stelle, wieso erhalte ich, wenn es denn
>> nötig wäre, keinerlei Rueckmeldungen seitens des Compilers?
>
> Der Compiler ist kein Debugger.

Der Compiler hat nichts mit der Codeausführung zu tun. Verwende entweder 
einen Debugger, dann siehst Du ja wo Du hängenbleibst oder wenn man 
Systemcalls beobachten möchte, dann kannst Du ja strace unter Linux 
aufprobieren. printf() solltest Du schön verfolgen können.

Manche Warnungen muss man auch explizit aktivieren bzw. wenn man selber 
Code schreibt, dann sollte man auch Warnungen als Fehler behandeln 
lassen.

Machst Du an anderen Stellen im Code noch etwas mit Deskriptoren. 
Schließt den falschen oder änderst Eigenschaften?

von Rolf M. (rmagnus)


Lesenswert?

mar IO schrieb:
> oder wenn man
> Systemcalls beobachten möchte, dann kannst Du ja strace unter Linux
> aufprobieren. printf() solltest Du schön verfolgen können.

Dann muß man im Output aber nicht nach printf(), sondern nach write() 
schauen.

von mar IO (Gast)


Lesenswert?

Rolf Magnus schrieb:
> mar IO schrieb:
>> oder wenn man
>> Systemcalls beobachten möchte, dann kannst Du ja strace unter Linux
>> aufprobieren. printf() solltest Du schön verfolgen können.
>
> Dann muß man im Output aber nicht nach printf(), sondern nach write()
> schauen.

Oder nach dem, was man ausgeben möchte.

von Matthias (Gast)


Lesenswert?

'strace' war mir neu, daher habe ich erst mal danach geixquicked und 
habe das gefunden.

> As strace only details system calls, it cannot be used to detect as many 
problems as a code debugger such as GNU Debugger (gdb).

Da mir gdb nicht ganz so fremd wie strace ist, habe ich mein Programm 
einmal damit untersucht und den Fehler widerum an einer ganz anderen 
Stelle lokalisiert und behoben.

Da sich das Ereignis erst zur Laufzeit ergeben hat ist jetzt auch klar, 
wieso der Compiler sich nicht gemeldet hat. Haette man, oder ich in 
diesem Fall, auch eher drauf kommen koennen!

Kurioserweise haben die Ausgaben ueber die Standardausgabe nach dem 
eingangs erwaehnten Codesegment ihren Dienst quittiert, wobei der 
eigentliche Fehler laut 'gdb' aber erst 30 Codezeilen spaeter verursacht 
worden ist.

Ich habe einmal in einem C-Buch gelesen, dass es die 'einfachste' Art 
des "Debugging" ist, sein Programm mit printf()-Funktionen und hierin 
enthaltenen Rueckgaben zu versehen.

Deshalb bin ich immer bei dem obigen Code gelandet. Ich denke, ich werde 
mich jetzt oefter auf 'gdb' verlassen, sollte erneut ein Laufzeitproblem 
auftreten.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.