Hallo Gemeinschaft! Ein gesundes neues Jahr wünsche ich ...
Ich habe ein ganz blödes Problem.
Ein ANSIC Linux-Deamon (RaspberryPI), der via SYSFS (I2C, DS2482)
DS1820-Temperatur-Sensoren ausliesst und per HTTP_POST an eine
Middleware schickt.
Läuft ein paar Stunden 1A! und bleibt dann ohne auch nur das
kleinste Anzeichen stehen :-(
https://raw.github.com/w3llschmidt/1wirevz/master/1wirevz.c
Der Kern ist die while(1)-Schleife in main() + ds1820read() +
http_post().
Keine spur in den Logs (syslog, messages, appache2) ...
Die Sysfs-Devices sind verfügbar und antworten ...
cat /sys/bus/w1/devices/28-0000042b410e/w1_slave
e1 01 4b 46 7f ff 0f 10 90 : crc=90 YES
e1 01 4b 46 7f ff 0f 10 90 t=30062
---
Gibt es eine Möglichkeit den Code in einem Debugger laufen zu lassen,
um zu sehen wo der stehen bleibt?
Wie gesgat, es läuft ganz sauber Stunden durch!
Grüsse, Henrik!
Hi Rufus ...
ja, GDB ist mit drauf ...
Reicht es im ersten Schritt mit 'gcc -g' zu compilieren und dann den
Deamon mit 'gdb deamon' + 'run' laufen zu lassen?
Schmeisst der GDB dann was raus? Oder muss ich von Hand breakpoints
setzen?
Einfach ohne Breakpoints laufen lassen.
GDB meldet nur den Grund, wenn das Programm angehalten wird (etwa durch
Breakpoint oder segmentation fault), ansonsten läuft das Programm
einfach. Du kannst das Programm aber manuell in GDB mit Ctrl+C
unterbrechen nachdem es nicht mehr reagiert und dann nachsehen, ob du
den Grund entdeckst.
Andreas B. schrieb:> einfach. Du kannst das Programm aber manuell in GDB mit Ctrl+C> unterbrechen nachdem es nicht mehr reagiert und dann nachsehen, ob du> den Grund entdeckst.
Alles klar! Danke!
Mal sehen was es ist ... ist echt nervig :-(
Außerdem gibt es auch die Möglichkeit, einen GDB nachträglich an einen
Prozess zu koppeln, falls man das Programm nicht aus GDB heraus
gestartet hat. Im GDB statt "run" das Kommando "attach PID" verwenden,
wobei PID für die Prozessnummer steht.
Andreas B. schrieb:> Außerdem gibt es auch die Möglichkeit, einen GDB nachträglich an einen> Prozess zu koppeln, falls man das Programm nicht aus GDB heraus> gestartet hat. Im GDB statt "run" das Kommando "attach PID" verwenden,> wobei PID für die Prozessnummer steht.
Oder gleich beim Starten von GDB: "gdb EXECUTABLE PID" (mit den
offensichtlichen Ersetzungen).
Leider kein Erfolg ... gdb schweigt, syslog schweigt, der Schöpfer
schweigt.
Das Programm bleibt einfach stehen :-(
Gibts irgendeine Möglichkeit zu 'sehen' in welcher Codezeile es hängt?
Henrik~
Und zusätzlich solltest du dringend mal die Warnungen die dir der
Compiler gibt ansehen, und am Besten auch noch zusätzliche Warnungen
aktivieren. Noch besserer wäre, damit man nicht in Versuchung kommt,
Warnungen als Fehler zu betrachten.
Einfach mal das Programm mit:
gcc -Wall -Wextra -Werror <andere-parameter-wie-zuvor>
compilieren.
Dann fallen einem auch solche Sachen auf, wie dass die Funktion "double
ds1820read(...)" unter Umständen gar nichts zurück gibt.
Sven B. schrieb:> Wenn das Programm stehen bleibt, in gdb Ctrl+C und dann "backtrace". Das> sagt dir, in welcher Zeile es steht.
Alles klar, teste ich, danke!
Mkay, 'i' ist in dem Fall die Anzahl der 1W-Master (3 Stück)
/sys/bus/w1/devices/w1_bus_master1/w1_master_slaves
/sys/bus/w1/devices/w1_bus_master2/w1_master_slaves
/sys/bus/w1/devices/w1_bus_master3/w1_master_slaves
Die sind fest verlötet, das sollte sich nie ändern ?!
> Außerdem ist mir der Sinn der Zeile>>
thomil schrieb:> Und zusätzlich solltest du dringend mal die Warnungen die dir der> Compiler gibt ansehen, und am Besten auch noch zusätzliche Warnungen> aktivieren. Noch besserer wäre, damit man nicht in Versuchung kommt,> Warnungen als Fehler zu betrachten.>> Einfach mal das Programm mit:>> gcc -Wall -Wextra -Werror <andere-parameter-wie-zuvor>>
Hab ich! Kommt nichts zurück ...
>> Dann fallen einem auch solche Sachen auf, wie dass die Funktion "double> ds1820read(...)" unter Umständen gar nichts zurück gibt.
Was meinstn konkret?
Lukas K. schrieb:> mal strace drauf losgelassen? Das loggt dir alle syscalls, die dein> Programm tätigt.
Läuft schon seit ner Stunde :-)
Hatte ich paralell gefunden! Tolles Tool!
Danke für den Tip!
Henrik Wellschmidt schrieb:> Mkay, 'i' ist in dem Fall die Anzahl der 1W-Master (3 Stück)
Ja ich versteh schon wofür das 'i' gut ist. Das Problem ist, dass du das
Array so definiert hast:
char sensorid[3][64][17];
Welche indices sind jetzt für sensorid gültig? Richtig, 0, 1, und 2. Du
greifst aber mit 1, 2 und 3 darauf zu. Der index 3 ist außerhalb des
Speicherbereichs den du für sensorid reserviert hast.
Bei 'vzuuid' selbes Spiel.
>> Dann fallen einem auch solche Sachen auf, wie dass die Funktion "double>> ds1820read(...)" unter Umständen gar nichts zurück gibt.> Was meinstn konkret?
Sieh dir einfach mal die Funktion an. Es ist möglich dass die Funktion
das Ende erreicht, ohne jemals ein "return" ausgeführt zu haben.
Dass der gcc bei dir keine Warnungen ausgibt wenn du -Wall -Wextra
verwendest kann ich nicht glauben. Bei mir gibt er alleine ohne diese
Optionen schon ein paar Warnungen aus.
Sven B. schrieb:> Kompilier' einfach mal mit -Wall -Werror, dann siehst du es. ;)> Damit dürfte sich das gar nicht übersetzen lassen.
Ich schwöre ... kein Mux!
thomil schrieb:> char sensorid[3][64][17];>> Welche indices sind jetzt für sensorid gültig? Richtig, 0, 1, und 2. Du> greifst aber mit 1, 2 und 3 darauf zu. Der index 3 ist außerhalb des> Speicherbereichs den du für sensorid reserviert hast.> Bei 'vzuuid' selbes Spiel.
Jetzt ja! Danke! Das is blöd ... muss ich ändern ...
Henrik Wellschmidt schrieb:> Ich schwöre ... kein Mux!> pi@rpi ~/1wirevz $ sudo gcc -Wall -Wextra -Werror -o /usr/sbin/1wirevz 1wirevz.c
-lconfig -lcurl
> pi@rpi ~/1wirevz $
Tatsächlich. Auf der pi bekomme ich mit dem aktuellsten Code mit
gcc-4.6.3 mit -Wall -Wextra keine Warnung.
Unter Ubuntu auf x86_64, ebenfalls mit gcc-4.6.3 findet er noch eine
-Wformat Warnung.
Was mir aber gerade beim tippen auffällt ist, dass diese Warnungen
wahrscheinlich durch unterschiedliche libconfig versionen zustande
kommen.
Wenn ich aber am PC optimierungen aktiviere( -Wall -Wextra -O2 ) bekomme
ich eine ganze Seite voller Warnungen. Auf der pi noch immer keine
Einzige. Auch nicht wenn ich sie explizit aktiviere.
Die Warnings am PC beziehen sich auf ignorierte Rückgabewerte von fgets,
chdir und write.
Immerhin weis ich jetzt, dass ich in Zukunft den raspian gcc bei
Warnungen nicht trauen kann.
Henrik Wellschmidt schrieb:> Sven B. schrieb:>> Kompilier' einfach mal mit -Wall -Werror, dann siehst du es. ;)>> Damit dürfte sich das gar nicht übersetzen lassen.>> Ich schwöre ... kein Mux!
Hihi, ja, mein Fehler. Ich hab das return in der ...read()-Funktion
übersehen, weil Du das so komisch eingerückt hast (das gehört eins
weiter nach rechts! ;)
Ich schätze mal, meinem Vorrender ging es da genauso.
Scheint so, als würde sich syslog verschlucken, bau den doch mal aus.
So spontan fällt mir noch auf -1 EMFILE (Too many open files).
Was sagt ulimit -a dazu?
Lukas K. schrieb:> Scheint so, als würde sich syslog verschlucken, bau den doch mal aus.> So spontan fällt mir noch auf -1 EMFILE (Too many open files).> Was sagt ulimit -a dazu?
Hi Lukas, nee ick globe is nicht der syslog :-)
Henrik Wellschmidt schrieb:> Schon viel besser :-)
Wenn du nur das fclose verschoben hast, dann ist da immer noch eine
Lücke, wo die "Datei" offen bleibt.
Sven B. schrieb:> Tipp: Ordentliche Einrückung vermeidet solche Fehler! ;D
Dem stimme ich zu. Mehrere "returns" machen den Code auch
unübersichtlich. Einmal am Ende der Funktion recht auch. Dann muß man
etwas anders codieren :)
900ss D. schrieb:> Henrik Wellschmidt schrieb:>> Schon viel besser :-)>> Wenn du nur das fclose verschoben hast, dann ist da immer noch eine> Lücke, wo die "Datei" offen bleibt.
Hi 900ss ... wo meinst ?
900ss D. schrieb:> Wenn der crc check fehl schlägt?
**sichmitderhandvornkoppklatscht**
Danke ;-)
Muss ich in jedem Fall 'return(temp)' zurückgeben ... ?
Hier noch ein paar anregungen zu ds1820read(), und zum ganzen Code im
allgemeinen:
Installier dir das Programm "indent". Das rückt dir den code automatisch
so ein, wie du es mit den command line parametern angibst. Dafür gibt es
auch vordefinierte styles, wie den linux coding style. Dafür einfach
mit:
indent -linux foo.c
und die Datei foo.c ist hinterher im Linux coding style eingerückt.
Wenn man das auf deine Funktion ds1820read() loslässt sieht diese schon
mal viel übersichtlicher aus.
Ich war mal so frei und habe außerdem ein paar Kommentare in den Code
eingefügt.