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álvaindex = 0,1, 2, ... 999
. Afor
hurok utolsó iterációjában azonban a program megpróbál hozzáférni afoo
– hoz. Ez egy segfault-ot eredményez, ha a memória helye afoo
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 a0, 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. Afoo2
elérése valószínűleg segfault-ot eredményez.
- Ha Egy tömb
- 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 olvasni0
meghatározása szerintfoo
. - 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
acore
g 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.