SIGSEV ohne Grund (?)



  • Hallo,

    Ich schreibe mir gerade ein kleines Helper-Programm um nackte Byte-Werte auf Device-Files zu schreiben. Das folgende Programm wird durch ein SIGSEV (Segmentation Fault) beendet. Dabei mache ich zum Schluss ja nix verbotenes, oder? Strace konnte mir nicht verraten warum.

    //open device file
    	int fdevice = 0;
    	if ( (fdevice= fopen( argv[1], "w+")) == NULL ){
    		  printf( "failed to open port\n" );
    				  exit(EXIT_FAILURE);
    	}
    
    	short hexvalue= 0;
    	// convert string to hex
    	sscanf( argv[2] , "%x", &hexvalue );
    
    	printf("Debug: Will write %d \n", hexvalue);
    
    	printf("Debug: sizeof(hexvalue) is %d \n", sizeof(hexvalue));
    
    	size_t writtenbytes = fwrite (&hexvalue , 1 , sizeof(hexvalue) , fdevice );
    	printf("Debug: written %d bytes \n", writtenbytes);
    	fclose (fdevice);
    	printf("Debug: Device closed \n");
    

    Gibt die Ausgabe:

    Debug: Will write -1 
    Debug: sizeof(hexvalue) is 2 
    Debug: written 2 bytes 
    Debug: Device closed 
    Segmentation fault
    

    Sieht jemand das Problem. Danke für die Hilfe



  • Und was passiert danach? Der Codeausschnitt zeigt nur den Bereich, der offenbar funktioniert.

    Was sagt der Debugger?



  • maus_on_c schrieb:

    int fdevice = 0;
    	if ( (fdevice= fopen( argv[1], "w+")) == NULL ){
    

    Aua, das funktioniert? fopen gibt FILE* zurück, nicht int. Bekommst du nicht wenigstens Warnungen? Hast du stdio.h eingebunden?



  • Was danach passiert:

    return EXIT_SUCCESS;
    }
    

    Damit wäre das Ende der Main bereits erreicht. Vor dem geposteten Code-Ausschnitt teste ich noch den argumentenvektor, was aber nicht das Problem sein sollte:

    if (argc != 3)
    	  	{
    	    	printf("Usage:Hexdump\n");
    	    	printf("Usage: hexdump /dev/gpioX ff  \n");
    	    	exit( EXIT_FAILURE );
    	 	}
    

    Danke für die Hilfe



  • Bashar schrieb:

    Aua, das funktioniert? fopen gibt FILE* zurück, nicht int. Bekommst du nicht wenigstens Warnungen? Hast du stdio.h eingebunden?

    Uups. Danke Bashar - habe die Korrektur angebracht. Aber immer noch gleiches Problem: Segmentation Fault.

    Hier nochmals der ganze Quelltext:

    #include <stdio.h>
    #include <stdlib.h>
    #include <termios.h>
    int main(int argc, char* argv[]) {
    	if (argc != 3)
    	  	{
    	    	printf("Usage:Hexdump\n");
    	    	printf("Usage: hexdump /dev/gpioX ff  \n");
    	    	exit( EXIT_FAILURE );
    	 	}
    
    	//open device file
    	FILE * fdevice = 0;
    	if ( (fdevice= fopen( argv[1], "w+")) == NULL ){
    		  printf( "failed to open port\n" );
    				  exit(EXIT_FAILURE);
    	}
    
    	short hexvalue= 0;
    	// convert string to hex
    	sscanf( argv[2] , "%x", &hexvalue );
    
    	printf("Debug: Will write %d \n", hexvalue);
    
    	printf("Debug: sizeof(hexvalue) is %d \n", sizeof(hexvalue));
    
    	size_t writtenbytes = fwrite (&hexvalue , 1 , sizeof(hexvalue) , fdevice );
    	printf("Debug: written %d bytes \n", writtenbytes);
    	fclose (fdevice);
    	printf("Debug: Device closed \n");
    
    	return EXIT_SUCCESS;
    }
    

    gcc kompiliert mit Warnhinweis auf Zeile 30:
    hexdump.c:30: Warnung: format »%x« erwartet Typ »unsigned int *«, aber Argument 3 hat Typ »short int *«



  • %hx



  • Kompilier am besten mit gcc -Wall -Wextra -std=c99 -pedantic_errors , damit du alle Warnungen bekommst.

    Ansonsten verwende einfach Valgrind (oder DUMA, gdb) um den Fehler zu finden.



  • MFK schrieb:

    %hx

    Danke MFK. Der richtige Längen-Modifier in der scanf-Funktion hat das Problem gelöst. Anstelle von %x für int funktioniert es mit %hx für short, entsprechend der Zielvariable.

    Der Segmentation Fault tritt nicht mehr auf.

    Kann mir jemand erklären warum der Seg.Fault erst nach Verlassen der Funktion auftritt und nicht schon bei der Verarbeitung von der scanf-Anweisung.

    Danke für eure Hilfe. 👍 👍 👍 (Gütesiegel)



  • maus_on_c schrieb:

    Kann mir jemand erklären warum der Seg.Fault erst nach Verlassen der Funktion auftritt und nicht schon bei der Verarbeitung von der scanf-Anweisung.

    Kurz: Undefiniertes Verhalten.

    Lang: Vermutlich braucht die Laufzeit nach Verlassen der main noch irgendwas, was auf dem Stack hinter hexvalue liegt. Du hast mit dem scanf n=(sizeof int - sizeof short) Bytes hinter hexvalue "zerstört".


Anmelden zum Antworten