SIGILL bei va_start

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
mase76
Beiträge: 1353
Registriert: 19.06.2004 08:57:32

SIGILL bei va_start

Beitrag von mase76 » 01.11.2008 21:26:01

Hallo!
Ich habe mal ne Frage an die Programmierer unter euch. Kann sein, dass hier das falsche
Forum für sowas ist, aber ich nehme stark an, dass g++-4.3 hierfür fehlerhaften Code generiert.
Jedenfalls kann ich keinen Quellcodefehler entdecken.
Ich habe folgende Funktion, in die cstdarg included habe. Das Programm bricht bei va_start
mit einem SIGILL ab.

Code: Alles auswählen

ERRNO cGenericDevice::SendCommand(unsigned _Direction, unsigned _Command, ...) 
 { 
     m_Command.clear(); 
 
     if (SendENQ()) 
     { 
          return ERR_NAK; 
     } 
 
     if (ReceiveACK()) 
     { 
          return ERR_NAK; 
     } 
 
     unsigned CommandSize; 
     unsigned checksum = 0xff; 
 
     m_Command.push_back(STX); 
 
     m_Command.push_back(_Direction); 
     CommandSize++; 
     checksum -= _Direction; 
 
     m_Command.push_back(_Command); 
     CommandSize++; 
     checksum -= _Command; 
 
     va_list morebytes; 
     va_start(morebytes, _Command); 
     unsigned char tempbyte; 
 
     for (;;) 
     { 
         tempbyte = va_arg(morebytes, unsigned char); 
 
         if (tempbyte == '\0') 
         { 
             break; 
         } 
 
         m_Command.push_back(static_cast<unsigned>(tempbyte)); 
         CommandSize++; 
         checksum -= tempbyte; 
     } 
 
     va_end(morebytes); 
 
     if (SendByte(CommandSize)) 
     { 
         return ERR_NAK; 
     } 
 
     checksum -= CommandSize; 
 
     m_Command.push_back(checksum); 
     m_Command.push_back(ETX); 
 
     if (SendByteVector(m_Command)) 
     { 
         return ERR_NAK; 
     } 
 
     return ERR_OK; 
 }
Weiss jemand, was da falsch gelaufen ist?

Benutzeravatar
king-crash
Beiträge: 742
Registriert: 08.08.2006 12:07:56
Lizenz eigener Beiträge: MIT Lizenz

Re: SIGILL bei va_start

Beitrag von king-crash » 02.11.2008 13:57:38

Dass der Fehler an der Stelle geschieht, kann ein Trugschluss sein. Irgendwo sonst im Code könntest du dir mit Zugriffen auf zu kleine Arrays etc was im Programmcode zerhauen haben. Mein Tipp (weils bei mir schon vielfach geholfen hat) jeden Zugriff auf ein Array mal Testweise überprüfen, ob er nicht darüber hinaus geht.

Code: Alles auswählen

if(i >= arraylaenge)
   {
   printf("Fehler Stelle xy");
   exit(0);
   }
array[i] = 2;
Vergiss aber nicht auch lesende Zugriffe zu Überprüfen.

Bzw probier doch einfach mal ne andere Version...

mase76
Beiträge: 1353
Registriert: 19.06.2004 08:57:32

Re: SIGILL bei va_start

Beitrag von mase76 » 02.11.2008 14:18:06

Ich habe in diesem Programm keine Arrays verwendet, sondern nur Vectoren.
Ich versuche generell, Arrays zu vermeiden.

Benutzeravatar
GoKi
Beiträge: 2068
Registriert: 04.07.2003 23:08:56
Lizenz eigener Beiträge: MIT Lizenz

Re: SIGILL bei va_start

Beitrag von GoKi » 02.11.2008 15:11:13

Ich würde auch mal mit valgrind schauen, ob soweit alles in Ordnung ist.
Auch bei vector<> wird beim []-Operator keine Überprüfung der Arraygrenzen durchgeführt, dies passiert nur bei at().
MfG GoKi
:wq

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Re: SIGILL bei va_start

Beitrag von gms » 23.11.2008 21:50:15

das hätte ich jetzt auch nicht umbedingt vermutet, aber anscheinend wird von va_start kein "unsigned char" unterstützt:

Code: Alles auswählen

x.cpp: In function 'int myfunc(unsigned int, unsigned int, ...)':
x.cpp:15: warning: 'unsigned char' is promoted to 'int' when passed through '...'
x.cpp:15: warning: (so you should pass 'int' not 'unsigned char' to 'va_arg')
x.cpp:15: note: if this code is reached, the program will abort
mit dem Compiler hat das aber nichts zu tun, konnte ich bei mir mit 3.4 - 4.3 reproduzieren

wenn möglich versuche "unsigned" statt "unsigned char" zu verwenden, das sollte klappen

edit: ist vielleicht etwas mißverständlich ausgedrückt: Bei dem Aufruf dieser Funktion cGenericDevice::SendCommand, kannst du auch weiterhin "unsigned char" verwenden, nur beim Aufruf von "va_start" mußt du dann "unsigned" oder "int" verwenden


Gruß
gms

mase76
Beiträge: 1353
Registriert: 19.06.2004 08:57:32

Re: SIGILL bei va_start

Beitrag von mase76 » 24.11.2008 14:28:23

Mittlerweile hab ich uint drin, anstatt uchar. Aber ich hab das ganze jetzt ohne va programmiert.
Ich werd bei Gelegenheit mal den Beispielcode mit uchar testen. Dann müsste er ja auch
aussteigen.

Antworten