[vz-dev] Antwort: Re: vzlogger - neuer Meter & Entwicklungsumgebung

Nico Prenzel nico.prenzel at pn-systeme.de
Mon Apr 29 10:41:54 CEST 2013


Hallo Peter,

ich habe einen segfault in MeterMap::stopped() bekommen, weil running() einen uninitialisierten Wert für _thread_running zurückliefert und daher dann pthread_join auf einen,in meinem Falle nicht gestarteten, Thread warten soll.

bool MeterMap::stopped() {
if(_meter->isEnabled() && running() ) {
if( pthread_join(_thread, NULL) == 0 ) {                  //segfault


Innerhalb meines MeterEMT7110::open der ziemlich ähnlich zum D0-Meter ist bekomme ich einen ERR="No such file or directory" bzw. ERR=-1 zurück.
int MeterEMT7110::open() {
if (_device != "") {
_fd = _openDevice(&_oldtio, _baudrate);
}
return (_fd < 0) ? ERR : SUCCESS;
}

Dies führt dann im Meter:open() dazu, dass eine ConnectionException geworfen wird...
void Meter::open() {
	if( _protocol->open() < 0) {
		print(log_error, "Cannot open meter", name());
		throw vz::ConnectionException("Meteropen failed.");
	}

}

... und da im MeterMapp.cpp die Exception NICHT behandelt wird, wird kein neuer Thread gestartet (was ja auch korrekt ist)! 
void MeterMap::start() {
	if(_meter->isEnabled()) {
		_meter->open();
		print(log_info, "Meter connection established", _meter->name());
		pthread_create(&_thread, NULL, &reading_thread, (void *) this);
		print(log_debug, "Meter thread started", _meter->name());



Evtl. kannst du ja auch gleich den u.g. else-Zweig in MeterMap::stopped einfügen:
Damit wird sichergestellt, dass im vzlogger.cpp die /* wait for all threads to terminate */ - Schleife beendet werden kann, wenn ein Meter-Thread gar nicht mehr läuft und somit dein exit(1) in Zeile 428 der vzlogger.cpp nicht mehr notwendig wird (exit(1) => verursacht zudem andere Probleme an dieser Stelle (memoryleaks, http-server, filehandle))

bool MeterMap::stopped() {
	if(_meter->isEnabled()  && running() ) {
		if( pthread_join(_thread, NULL) == 0 ) {
			_thread_running = false;

			// join channel-threads
			for(iterator it = _channels.begin(); it!=_channels.end(); it++) {
				(*it)->cancel();
				(*it)->join();
			}
			return true;
		}
	}
	else
	{
		return true;
	}
	return false;
}





Nächster Fehler:
Gibt man ein nicht hinterlegtes Protokol in der vzlogger.conf an. z.B:

"meters" : [{

	"enabled" : true,	/* disabled meters will be ignored */
	"protocol" : "undefiniert",
...

dann läuft die folgende Iteration meistens in einen segfault:

int meter_lookup_protocol(const char* name, meter_protocol_t *protocol) {
	for (const meter_details_t *it = meter_get_protocols(); it != NULL; it++) {   // segfault
		if (strcmp(it->name, name) == 0) {
			*protocol = it->id;
			return SUCCESS;
		}
	}
	return ERR_NOT_FOUND;
}


Ersetzt man die Zeile 
-for (const meter_details_t *it = meter_get_protocols(); it != NULL; it++) {
+for (const meter_details_t *it = meter_get_protocols(); strcmp(it->name, "none"); it++) {
... ist zumindest mal der segfault weg.



War das noch alles verständlich?


Viele Grüße

NicoP.


-----volkszaehler-dev-bounces at lists.volkszaehler.org schrieb: ----- 
An: "volkszaehler.org" <volkszaehler-dev at lists.volkszaehler.org>
Von: Peter Evertz 
Gesendet von: volkszaehler-dev-bounces at lists.volkszaehler.org
Datum: 28.04.2013 19:52
Betreff: Re: [vz-dev] Antwort: Re: vzlogger - neuer Meter & Entwicklungsumgebung


Dein Patch lasst sich bei mir kompilieren. Bei meine Compiler (gcc) ist 
es verboten in der Klassenvariablendeklaration eine initialisierung 
vorzunehmen. Ich habe die Initialisierung in den Konstructor übernommen 
( wo es auch  hingehört). Ändert für mich aber nichts am Problem der 
exception wenn die meter.open() eine exception wirft.

Ich habe es jetzt so umgebaut ( in vzlogger.c im catch ein exit ) das er 
jetzt normal terminiert wenn es beim starten der Meter eine Exception gibt.

Welchen Segfault bekommtst Du beim beenden ? Etwas mit "free()" ? Das 
ist ein Bug in der Curl-Lib in manchen versionen.

Schau mal git 
https://github.com/peterevertz/vzlogger/commit/50751e73533346a6e5a5b59ce94198888cbdefc9

Grüße
Peter
Am 27.04.2013 13:50, schrieb Nico Prenzel:
> Hallo Peter,
>
> anbei ein (sehr simpler) Patch den du vielleicht auch in deinen vzlogger
> Branch integrieren kannst. (gilt natürlich auch für den allgemeinen
> vzlogger)
>
> Hatte während meiner Entwicklungstests festgestellt, dass ich immer einen
> segfault bekomme wenn mein USB Device nicht angesteckt war.
> (Meter::open()... wirft eine Exception)
>
>
>
> Grüße
>
> Nico
>
>
>
>
> Von:    Peter Evertz <leo2 at pec.homeip.net>
> An:     "volkszaehler.org" <volkszaehler-dev at lists.volkszaehler.org>
> Datum:  23.04.2013 16:41
> Betreff:        Re: [vz-dev] vzlogger - neuer Meter & Entwicklungsumgebung
> Gesendet von:   volkszaehler-dev-bounces at lists.volkszaehler.org
>
>
>
> Am 23.04.2013 12:40, schrieb Thorben Thuermer:
>> On Tue, 23 Apr 2013 09:30:53 +0200
>> Nico Prenzel <nico.prenzel at pn-systeme.de> wrote:
>>> möchte ich mich erstmal um eine anständige Entwicklungsumgebung mit
>>> Debug-Funktionalität kümmern.
>>> Was für eine IDE setzt ihr denn bisher für die vzlogger Entwicklung
> ein?
>> einen texteditor, make, einen c-compiler?
>> gdb zum debuggen? aber ich bin scheinbar eh der einzige der das tut.
>>
>>> Zum Problem mit dem neuen MeterEMT7110:
>>> Immerhin habe ich es schonmal geschafft, das RF-Soap Modul anzubinden
>>> und die gewünschten Daten auszulesen. Nur habe ich jetzt
> Schwierigkeiten
>>> die empfangenen Daten korrekt in der middleware zu speichern. Irgendwo
> bei
>>> der Zuordnung von gemessenem/empfangen Wert und dem Channel stimmt
> etwas nicht.
>>> Evtl. verwende ich auch den falschen Identifier bzw. StringItentifier!?
>>> Kann mir dabei jemand weiterhelfen. Ich stehe wohl auf dem Schlauch für
> was
>>> genau die StringItentifier oder NilItentifier usw. eingesetzt werden
> sollen.
>> auf der ebene der API existieren die garnicht, das sind
> vzlogger-interna.
>> in der api/middleware gibt es nur ueber die UUID identifizierte kanaele,
>> in die daten gespeichert werden.
>>
>>> Meine vzlogger.conf meter Konfiguration:
>>> "meters" : [{
>> [...]
>>> "channels" : [{
>>> "uuid" : "4bf20df0-a908-11e2-9738-b760d94f1697",
>>> "middleware" : "http://localhost/volkszaehler/middleware.php",
>>> "identifier" : "Power",
>>> }, {
>>> "uuid" : "202db620-a908-11e2-b294-916f2f6ce2d1",
>>> "middleware" : "http://localhost/volkszaehler/middleware.php",
>>> "identifier" : "Current"
>>> }, {
>> [..]
>>> Anbei poste ich mal mein Logging. Vielleicht kann man mir damit schon
> jemand weiterhelfen.
>> [...]
>>> [Apr 21 13:47:05][mtr0] found channel
>>> [Apr 21 13:47:05][chn0] Adding reading to queue (value=1.00
> ts=1366544825.926)
>>> [Apr 21 13:47:05][mtr0] found channel
>>> [Apr 21 13:47:05][chn0] Adding reading to queue (value=70.00
> ts=1366544825.926)
>>> [Apr 21 13:47:05][mtr0] found channel
>>> [Apr 21 13:47:05][chn0] Adding reading to queue (value=227.50
> ts=1366544825.926)
>>> [Apr 21 13:47:05][mtr0] found channel
>>> [Apr 21 13:47:05][chn0] Adding reading to queue (value=4800.00
> ts=1366544825.926)
>>> [Apr 21 13:47:05][chn0] ==> number of tuples: 4
>> da werden wohl alle vier werte in den gleichen channel geloggt,
>> das wird dann im frontend entsprechend chaotisch aussehen...
>> an der stelle sind wohl die identifier noetig, um die korrekt
> zuzuordnen.
>> ich kenne die logik in der c++ version leider nicht...
>> in der C-version lief das noch ueber die OBIS-IDs,
>> die vom meter gelieferte und die in der config angegebene wurden
> verglichen
>> (inklusive einer zweifelhaften wildcard-logik) um die zuordnung
> herzustellen.
>> ich vermute mal du musst dich mit den identifiern und deren
> vergleichsoperatoren
>> beschaeftigen.
> Schau mal
> https://github.com/peterevertz/vzlogger/commit/82028e3d6c8f0ef28386f3e751494252b9309e21
>
> die Anpassung in Reading.cpp. Die Vergleichsopertoren der Indetfiere
> waren schlicht weg kaputt.
>
>
>
>>> Vielen Danke & viele Grüße
>>>
>>> Nico Prenzel
>> - Thorben
>


More information about the volkszaehler-dev mailing list