Indiana Egyetem Indiana Egyetem Indiana Egyetemen

ezen Az oldalon:

  • Áttekintés
  • Példa a közös segfaults
  • Találni kint tömb hivatkozások
  • Ellenőrizze a shell határértékek
  • a debuggers diagnosztizálni segfaults

Áttekintés

A szegmentációs hiba (aka segfault) gyakori állapot okozza, hogy a programok baleset; gyakran társul nevű fájlt core. Segfaults által okozott program próbál olvasni vagy írni egy illegális memória helyét.

a Program memória van osztva különböző szegmensek: egy szöveg szegmens a program utasításait, egy adatszegmens a változók, illetve tömbök meghatározott fordítási időben, egy stack szegmens ideiglenes (vagy automata) változók meghatározása a szubrutinok függvényt, egy halom szegmens a változók kiosztott során runtime által funkciók, mint például a malloc (C), majd a allocate (a Fortran). További információ a programszegmensekről.

a segfault akkor fordul elő, amikor egy változóra való hivatkozás kívül esik azon a szegmensen, ahol a változó lakik, vagy amikor írást kísérelnek meg egy olyan helyre, amely csak olvasható szegmensben található. A gyakorlatban a segfaults szinte mindig annak köszönhető, hogy megpróbál olvasni vagy írni egy nem létező tömb elemet, nem megfelelően definiálja a mutatót a használat előtt, vagy (C programokban) véletlenül egy változó értékét címként használja (lásd a scanf alábbi példát).

Példa a közös segfaults

  • például, hívja memset() alábbiak szerint okozna a program segfault:
    memset((char *)0x0, 1, 100);
  • A következő három eset illusztrálja a leggyakoribb típusú tömb kapcsolódó segfaults:

    az Esetben, ha Egy

    /* "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;

    B Eset

    /* 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;

    Case C

    /* Illegal memory access because no memory is allocated for foo2 */ float *foo, *foo2; foo = (float*)malloc(1000); foo2 = 1.0;

    • Ha Egy tömb foo definiálva index = 0,1, 2, ... 999. A for hurok utolsó iterációjában azonban a program megpróbál hozzáférni a foo – hoz. Ez egy segfault-ot eredményez, ha a memória helye a foo memóriaszegmensén kívül helyezkedik el. Még akkor is, ha nem okoz segfault-ot, ez még mindig hiba.
    • B esetben az egész szám n bármilyen véletlen érték lehet. Mint az A esetben, ha nem a 0, 1, ... 999 tartományban van, akkor segfault-ot okozhat. Függetlenül attól, hogy nem, ez minden bizonnyal egy hiba.
    • C esetben a foo2 változó memóriáját figyelmen kívül hagyták, így afoo2 véletlenszerű helyre mutat a memóriában. A foo2 elérése valószínűleg segfault-ot eredményez.
  • egy másik gyakori programozási hiba, amely segfaultshoz vezet, a mutatók használatának felügyelete. Például a C függvény scanf() elvárja a változó címét második paraméterként; ezért a következő valószínűleg a program összeomlását okozza egy segfault-val:
    int foo = 0; scanf("%d", foo); /* Note missing & sign ; correct usage would have been &foo */

    a foo változó a memória helyén definiálható 1000, de a fenti függvényhívás megpróbálja az egész adatokat a memória helyére olvasni 0 meghatározása szerint foo.

  • Egy segfault akkor fordul elő, ha egy program megpróbál működnek olyan memóriaterület, úgy, hogy nem megengedett (például kísérletek írni, olvasni-egyetlen hely, amelynek következtében a segfault).
  • a Segfaults akkor is előfordulhat, ha a program kifogy a veremterületből. Lehet, hogy ez nem hiba a programban, de lehet, hogy a héj miatt túl kicsi a verem méretének korlátozása.

Ismerje meg a határokat array referenciák

a legtöbb Fortran fordító van egy lehetőség, hogy beszúrja kódot csinálni határokat ellenőrzi az összes tömb referenciák futási idő alatt. Ha EGY hozzáférés a tömb indextartományán kívül esik, a program leáll, és megmondja, hol történik ez. A legtöbb Fortran fordító esetében az opció -C, vagy -check, majd egy kulcsszó. Lásd a fordító Felhasználói útmutató, hogy a pontos opciót. Csak hibakereséskor használja a határokat, mivel ez lelassítja a programot. Néhány C fordítóprogramnak van egy határellenőrzési lehetősége is.

ellenőrizze a shell limiteket

amint azt a fenti utolsó példában megjegyeztük, néhány segfault probléma nem a program hibáinak köszönhető, hanem inkább a rendszermemória határértékeinek túl alacsony beállítása okozza. Általában ez a verem méretének korlátozása okozza ezt a problémát. A memória határértékeinek ellenőrzéséhez használja a ulimit parancsot a bash vagy ksh vagy a limit parancsot a csh div>vagy tcsh. Próbálja meg magasabbra állítani a csomagméretet, majd futtassa újra a programot, hogy megnézze, eltűnik-e a segfault.

használja a hibakeresőket a

segfaults diagnosztizálásához ha nem találja a problémát más módon, megpróbálhat egy hibakeresőt. Például, akkor használd a GNU jól ismert debugger GDB megtekintéséhez a lenyomozni egy core fájl dobott a program; amikor a programok segfault, általában kidobni a tartalom (a szakasz a) a memória az, amikor lezuhant egy core fájl. Indítsa el a hibakeresőt a gdb core paranccsal, majd használja a backtrace parancsot, hogy megnézze, hol volt a program, amikor összeomlott. Ez az egyszerű trükk lehetővé teszi, hogy a kód azon részére összpontosítson.

ha abacktrace acoreg fájl nem találja a problémát, előfordulhat, hogy a programot hibakeresési ellenőrzés alatt kell futtatnia, majd egyszerre át kell lépnie a kód egy függvényén vagy egy forráskód vonalon. Ehhez optimalizálás nélkül kell összeállítania a kódot, a -g zászlóval, így a forráskód vonalakra vonatkozó információk beágyazódnak a végrehajtható fájlba. További információkért lásd lépésről lépésre példa a GDB használatára az Emacs-en belül a C orC++ program hibakereséséhez.

kapcsolódó dokumentumok

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük