Indiana University Indiana University Indiana University

På denne siden:

  • Oversikt
  • Eksempler på vanlige segfaults
  • Finn ut-av-grensene array referanser
  • Sjekk shell grenser
  • Bruk debuggere for å diagnostisere segfaults

oversikt

en segmenteringsfeil (aka segfault) er En Vanlig Tilstand som fører til at programmer krasjer; de er ofte knyttet til en fil Som Heter core. Segfaults er forårsaket av et program som prøver å lese eller skrive en ulovlig minneplassering.Programminnet er delt inn i ulike segmenter: et tekstsegment for programinstruksjoner, et datasegment for variabler og matriser definert ved kompileringstid, et stakksegment for midlertidige (eller automatiske) variabler definert i subrutiner og funksjoner, og et heap-segment for variabler tildelt under kjøretid av funksjoner, for eksempel malloc(I C) og allocate (I Fortran). Hvis du vil ha mer, kan Du se om programsegmenter.

en segfault oppstår når en referanse til en variabel faller utenfor segmentet der variabelen ligger, eller når en skrive er forsøkt til en plassering som er i et skrivebeskyttet segment. I praksis er segfaults nesten alltid på grunn av å prøve å lese eller skrive et ikke-eksisterende arrayelement, ikke riktig definere en peker før du bruker den, eller (I C-programmer) ved et uhell å bruke en variabels verdi som en adresse (se scanf eksempel nedenfor).

Eksempler på vanlige segfaults

  • hvis du for eksempel ringer memset() som vist nedenfor, vil et program føre til segfault:
    memset((char *)0x0, 1, 100);
  • Følgende tre tilfeller illustrerer de vanligste typene array-relaterte segfaults:

    Case A

    /* "Array out of bounds" error valid indices for array foo are 0, 1, ... 999 */ int foo; for (int i = 0; i <= 1000 ; i++) foo = i;

    /* Illegal memory access if value of n is not in the range 0, 1, ... 999 */ int n; int foo; for (int i = 0; i < n ; i++) foo = i;
    /* Illegal memory access because no memory is allocated for foo2 */ float *foo, *foo2; foo = (float*)malloc(1000); foo2 = 1.0;

    • I tilfelle a, Matrisefoo er definert for index = 0,1, 2, ... 999. Men i den siste iterasjonen av for – sløyfen prøver programmet å få tilgang til foo. Dette vil resultere i en segfault hvis den minneplasseringen ligger utenfor minnesegmentet der foo ligger. Selv om det ikke forårsaker en segfault, er det fortsatt en feil.
    • i tilfelle B kan integer n være en tilfeldig verdi. Som i tilfelle A, hvis det ikke er i området 0, 1, ... 999, kan det føre til en segfault. Enten det gjør det eller ikke, er det absolutt en feil.
    • i tilfelle C, tildeling av minne for variabelfoo2 har blitt oversett, såfoo2 vil peke til en tilfeldig plassering i minnet. Tilgang til foo2 vil trolig resultere i en segfault.
  • En annen vanlig programmeringsfeil som fører til segfaults er tilsyn med bruk av pekere. For eksempel Forventer c-funksjonen scanf() adressen til en variabel som sin andre parameter.:
    int foo = 0; scanf("%d", foo); /* Note missing & sign ; correct usage would have been &foo */

    variabelen foo kan defineres ved minneplassering 1000, men funksjonskallet ovenfor vil prøve å lese heltallsdata til minneplassering 0 i henhold til definisjonen av foo.

  • En segfault oppstår når et program forsøker å operere på en minneplassering på en måte som ikke er tillatt (for eksempel forsøk på å skrive en skrivebeskyttet plassering vil resultere i en segfault).
  • Segfaults kan også oppstå når programmet går tom for stack plass. Dette kan ikke være en feil i programmet, men kan skyldes i stedet for at skallet ditt angir stakkestørrelsesgrensen for liten.

Finn out-of-bounds matrisereferanser

De Fleste Fortran-kompilatorer har et alternativ som vil sette inn kode for å gjøre grensekontroll på alle matrisereferanser under kjøring. Hvis en tilgang faller utenfor indeksområdet som er definert for en matrise, stopper programmet og forteller deg hvor dette skjer. For De fleste Fortran-kompilatorer er alternativet-C, eller-check etterfulgt av et nøkkelord. Se kompilatorens brukerhåndbok for å få det nøyaktige alternativet. Bruk grensekontroll bare når feilsøking, siden det vil senke programmet. Noen c-kompilatorer har også et grensekontrollalternativ.

Sjekk shell grenser

som nevnt i det siste eksempelet ovenfor, noen segfault problemer er ikke på grunn av feil i programmet, men er forårsaket i stedet av systemminne grenser blir satt for lavt. Vanligvis er det grensen på stack størrelse som forårsaker denne typen problem. For å sjekke minnegrenser, bruk ulimit kommandoen i bash eller ksh, eller limit kommandoen i csh eller tcsh. Prøv å sette stacksize høyere, og kjør deretter programmet på nytt for å se om segfault går bort.

Bruk debuggere til å diagnostisere segfaults

hvis du ikke finner problemet på annen måte, kan du prøve en debugger. For eksempel kan DU bruke GNU velkjente debuggerGDB for å vise backtrace av en core fil dumpet av programmet; når programmer segfault, de vanligvis dumpe innholdet i (sin del av den) minne på tidspunktet for krasj i en core fil. Start debuggeren med kommandoen gdb core, og bruk deretter kommandoen backtrace for å se hvor programmet var da det krasjet. Dette enkle trikset lar deg fokusere på den delen av koden.

hvis du brukerbacktracecoreg-filen ikke finner problemet, må du kanskje kjøre programmet under feilsøkingskontroll, og deretter gå gjennom koden en funksjon, eller en kildekodelinje, om gangen. For å gjøre dette må du kompilere koden din uten optimalisering, og med -g flagget, så informasjon om kildekodelinjer vil bli innebygd i den kjørbare filen. For mer, se Trinnvis eksempel for BRUK AV GDB i Emacs for å feilsøke Et c orC++ – program.

Relaterte dokumenter

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *