ඛණ්ඩනය කිරීමේ දෝෂය යටින් ක්‍රියාත්මක වන්නේ කෙසේද?


264

"CPU හි MMU සං signal ාවක් යවයි" සහ "කර්නලය එය අවලංගු කිරීමේ වැඩසටහනට යොමු කරයි, එය අවසන් කරයි" හැරෙන්නට මේ පිළිබඳ කිසිදු තොරතුරක් මට සොයාගත නොහැක.

මම සිතුවේ එය බොහෝ විට ෂෙල් එකට සං signal ාව යවන අතර ෂෙල් විසින් එය හසුරුවන්නේ වැරදි ක්‍රියාවලිය අවසන් කර මුද්‍රණය කිරීමෙනි "Segmentation fault". ඒ නිසා මම ක්‍රෂ් ( ක්‍රැප් ෂෙල්) ලෙස හඳුන්වන අතිශය අවම කවචයක් ලිවීමෙන් එම උපකල්පනය පරීක්ෂා කළෙමි . පරිශීලක ආදානය ගෙන එය system()ක්‍රමයට පෝෂණය කිරීම හැර මෙම කවචය කිසිවක් නොකරයි .

#include <stdio.h>
#include <stdlib.h>

int main(){
    char cmdbuf[1000];
    while (1){
        printf("Crap Shell> ");
        fgets(cmdbuf, 1000, stdin);
        system(cmdbuf);
    }
}

ඒ නිසා මම මෙම කවචය හිස් පර්යන්තයක bashධාවනය කළෙමි ( යටින් ධාවනය නොකර ). ඉන්පසු මම සෙග්ෆෝල්ට් නිපදවන වැඩසටහනක් ක්‍රියාත්මක කළෙමි. මගේ උපකල්පන නිවැරදි නම්, මෙය අ) බිඳ වැටීම crsh, xterm වසා දැමීම, ආ) මුද්‍රණය නොකිරීම "Segmentation fault"හෝ ඇ) දෙකම.

braden@system ~/code/crsh/ $ xterm -e ./crsh
Crap Shell> ./segfault
Segmentation fault
Crap Shell> [still running]

පළමු වර්ගයට ආපසු, මම හිතන්නේ. මෙය සිදු කරන්නේ කවචය නොව යටින් ඇති පද්ධතිය බව මම නිරූපණය කර ඇත්තෙමි. "ඛණ්ඩනය කිරීමේ දෝෂය" පවා මුද්‍රණය වන්නේ කෙසේද? "කවුද" එය කරන්නේ? කර්නලය? වෙන මොනවා හරි? සං the ාව සහ එහි සියලු අතුරු ආබාධ දෘඩාංගයේ සිට අවසානයේදී වැඩසටහන අවසන් කිරීම දක්වා ව්‍යාප්ත වන්නේ කෙසේද?


30
මම මුලින්ම දුටු විට crsh, එය "කඩාවැටීම" ලෙස උච්චාරණය කරනු ඇතැයි මම සිතුවෙමි. එය සමානව ගැලපෙන නමක් දැයි මට විශ්වාස නැත.
jpmc26

56
මෙය කදිම අත්හදා බැලීමකි ... නමුත් ඔබ දැනගත යුත්තේ system()කබාය යටින් කරන්නේ කුමක්ද යන්නයි . එය system()ෂෙල් ක්‍රියාවලියක් ඇති කරන බව පෙනේ ! එබැවින් ඔබේ ෂෙල් ක්‍රියාවලිය තවත් ෂෙල් ක්‍රියාවලියක් ඇති කරන අතර එම ෂෙල් ක්‍රියාවලිය (බොහෝ විට /bin/shහෝ එවැනි දෙයක්) වැඩසටහන ක්‍රියාත්මක කරයි. මාර්ගය /bin/shහෝ bashවැඩ කිරීම භාවිතා කිරීම fork()සහ exec()(හෝ execve()පවුලේ වෙනත් කාර්යයක් ).
ඩියෙට්‍රික් එප්

2
Iet ඩියෙට්‍රිච් එප් භාවිතා කිරීම සම්බන්ධයෙන් යම් ආකාරයක අවවාදයක් ඇති බව මට හැඟුණි system(). Execvp භාවිතා කිරීම සඳහා මම ක්‍රෑෂ් නැවත ලිවීමක් එකට හැක් කළෙමි (එය දුෂ්කර වූ නමුත් ව්‍යාජ වැඩ කරන ආකාරය ගැන මට බොහෝ දේ කියා දුන්නේය), සහ අත්හදා බැලීම නැවත සිදු කළෙමි. සිත්ගන්නා සුළු ප්‍රති results ල තිබුනේ නම්: 1. කවචය තවමත් කඩා වැටී නැත. 2. එය "ඛණ්ඩනය කිරීමේ දෝෂය" මුද්‍රණය කර නැත . මෝඩ වැරැද්දක් කිරීමට ඉඩ තිබූ බැවින් මෙය තරමක් අවිනිශ්චිත බව මම දනිමි, නමුත් මා දකින දෙයින් පෙනෙන්නේ “බෙදීම් දෝෂය” මුද්‍රණය කිරීම සඳහා කවචය වගකිව යුතු බවයි. සිතුවිලි?
බ්‍රැඩන් හොඳම

4
Rad බ්‍රැඩන්බෙස්ට්: හරියටම. අත්පොත පිටුව කියවන්න man 2 wait, එයට මැක්‍රෝස් WIFSIGNALED()සහ WTERMSIG().
ඩියෙට්‍රික් එප්

4
IetDietrichEpp ඔබ කීවාක් මෙන්! (WIFSIGNALED(status) && WTERMSIG(status) == 11)මෝඩ දෙයක් ( "YOU DUN GOOFED AND TRIGGERED A SEGFAULT") මුද්‍රණය කිරීම සඳහා චෙක්පතක් එක් කිරීමට මම උත්සාහ කළෙමි . මම segfaultවැඩසටහන ඇතුළත සිට ක්‍රියාත්මක කරන විට crsh, එය හරියටම මුද්‍රණය කර ඇත. මේ අතර, සාමාන්‍යයෙන් පිටවන විධාන මඟින් දෝෂ පණිවිඩය නොලැබේ.
බ්‍රැඩන් හොඳම

Answers:


250

සියලුම නවීන CPU වලට දැනට ක්‍රියාත්මක වන යන්ත්‍ර උපදෙස් වලට බාධා කිරීමේ හැකියාව ඇත . කිසිවක් සිදු නොවූවාක් මෙන් පසුව ක්‍රියාත්මක කිරීම නැවත ආරම්භ කිරීමට හැකි වන පරිදි ඔවුන් ප්‍රමාණවත් තරම් රාජ්‍යයක් (සාමාන්‍යයෙන්, නමුත් සෑම විටම, තොගයේ) ඉතිරි කරයි (බාධා කළ උපදෙස් මුල සිටම නැවත ආරම්භ වේ). ඉන්පසු ඔවුන් බාධාකාරී හසුරුවන්නෙකු ක්‍රියාත්මක කිරීමට පටන් ගනී , එය තවත් යන්ත්‍ර කේතයක් වන නමුත් විශේෂ ස්ථානයක තබා ඇති බැවින් එය කල්තියා කොතැනදැයි CPU දැන ගනී. බාධා කිරීම් හසුරුවන්නන් සැමවිටම මෙහෙයුම් පද්ධතියේ කර්නලයේ කොටසකි : විශාලතම වරප්‍රසාදය සමඟ ක්‍රියාත්මක වන සංරචකය සහ අනෙකුත් සියලුම සංරචක ක්‍රියාත්මක කිරීම අධීක්ෂණය කිරීමේ වගකීම දරයි. 1,2

බාධා කිරීම් සමමුහුර්ත විය හැකි අතර , එයින් අදහස් වන්නේ ඒවා දැනට ක්‍රියාත්මක කර ඇති උපදෙස් වලට හෝ අසමමුහුර්ත දෙයකට සෘජු ප්‍රතිචාරයක් ලෙස CPU විසින්ම අවුලුවන බවයි , එයින් අදහස් වන්නේ ඒවා අනපේක්ෂිත වේලාවක සිදුවන්නේ බාහිර සිදුවීමක් නිසා, ජාලයට පැමිණෙන දත්ත වැනි බවයි. වරාය. සමහර අය අසමමුහුර්ත බාධා සඳහා "බාධා" යන යෙදුම වෙන් කර ඇති අතර ඒ වෙනුවට සමමුහුර්ත බාධා "උගුල්", "දෝෂ" හෝ "ව්‍යතිරේක" ලෙස හඳුන්වයි, නමුත් එම වචන සියල්ලටම වෙනත් අර්ථයන් ඇත, එබැවින් මම "සමමුහුර්ත බාධා කිරීම්" සමඟ බැඳී සිටිමි.

දැන් බොහෝ නවීන මෙහෙයුම් පද්ධතිවල ක්‍රියාවලි පිළිබඳ සංකල්පයක් ඇත . එහි මූලික වශයෙන්, මෙය පරිගණකයට එකවර එකකට වඩා වැඩියෙන් ක්‍රියාත්මක කළ හැකි යාන්ත්‍රණයකි, නමුත් මෙහෙයුම් පද්ධති මතක ආරක්ෂණය වින්‍යාස කරන ආකාරය පිළිබඳ ප්‍රධාන අංගයක් වන අතර එය බොහෝ දෙනාගේ ලක්ෂණයකි (නමුත් අහෝ, තවමත් සියල්ලම නොවේ ) නවීන CPUs. එය අථත්ය මතකය සමඟ ගමන් කරයි, එය මතක ලිපින සහ RAM හි සත්‍ය ස්ථාන අතර සිතියම් වෙනස් කිරීමේ හැකියාවයි. මතක ආරක්ෂණය මඟින් මෙහෙයුම් පද්ධතියට එක් එක් ක්‍රියාවලියට තමන්ගේම පුද්ගලික RAM ප්‍රමාණයක් ලබා දිය හැකිය. මෙහෙයුම් පද්ධතියට (කිසියම් ක්‍රියාවලියක් වෙනුවෙන් ක්‍රියා කිරීම) RAM හි කලාප කියවීමට-පමණක්, ක්‍රියාත්මක කළ හැකි, සහයෝගීතා ක්‍රියාවලීන් සමූහයක් අතර බෙදා ගැනීමට යනාදිය නම් කිරීමට ඉඩ ලබා දේ. කර්නලය. 3

සෑම ක්‍රියාවලියක්ම මතකයට ප්‍රවේශ වන තාක් කල් CPU වින්‍යාසගත කර ඇති ආකාරයට පමණක් මතක ආරක්ෂාව නොපෙනේ. ක්‍රියාවලියක් නීති රීති උල්ලං When නය කරන විට, CPU විසින් සමමුහුර්ත බාධාවක් ජනනය කරනු ඇත. එය නිතිපතා සිදුවන්නේ ක්‍රියාවලිය සැබවින්ම නීති කඩ නොකළ බවය, ක්‍රියාවලිය දිගටම කරගෙන යාමට ඉඩ දීමට පෙර කර්නලයට පමණක් යම් වැඩක් කළ යුතුය. නිදසුනක් ලෙස, වෙනත් දෙයක් සඳහා RAM හි ඉඩ නිදහස් කිරීම සඳහා ක්‍රියාවලියක මතකයේ පිටුවක් swap ගොනුවට "ඉවත් කිරීම" අවශ්‍ය නම්, කර්නලය එම පිටුව ප්‍රවේශ කළ නොහැකි ලෙස සලකුණු කරයි. ඊළඟ වතාවේ ක්‍රියාවලිය එය භාවිතා කිරීමට උත්සාහ කරන විට, CPU විසින් මතක ආරක්ෂණ බාධාවක් ජනනය කරනු ඇත; කර්නලය පිටුව swap වෙතින් ලබා ගනී, එය තිබූ තැනට නැවත තබයි, නැවත ප්‍රවේශ විය හැකි බව සලකුණු කර ක්‍රියාත්මක කිරීම නැවත ආරම්භ කරයි.

නමුත් ක්‍රියාවලිය ඇත්ත වශයෙන්ම නීති කඩ කළා යැයි සිතමු. එය කිසි විටෙකත් RAM සිතියම් ගත කර නැති පිටුවකට ප්‍රවේශ වීමට උත්සාහ කළේය, නැතහොත් එය යන්ත්‍ර කේතයක් නොමැති බව සලකුණු කර ඇති පිටුවක් ක්‍රියාත්මක කිරීමට උත්සාහ කළේය. සාමාන්‍යයෙන් "යුනික්ස්" ලෙස හැඳින්වෙන මෙහෙයුම් පද්ධතිවල පවුල මෙම තත්වය සමඟ කටයුතු කිරීම සඳහා සං als ා භාවිතා කරයි . 4 සංඥ නැවතුම් සමාන, නමුත් ඔවුන් කර්නලය විසින් ජනනය සහ වෙනුවට දෘඩාංග විසින් ජනනය හා කර්නලය විසින් කෙනෙක්ම, වඩා, ක්රියාදාමයන් විසින් කෙනෙක්ම, ඇත. ක්‍රියාවලි මඟින් සං signal ා හසුරුවන්නන් අර්ථ දැක්විය හැකියඔවුන්ගේ කේතයෙන්, ඔවුන් සිටින තැන කර්නලයට කියන්න. එම සං signal ා හසුරුවන්නන් අවශ්‍ය විටෙක සාමාන්‍ය පාලනයේ ප්‍රවාහයට බාධා කරමින් ක්‍රියාත්මක කරනු ඇත. සං als ා සියල්ලටම අංක සහ නම් දෙකක් ඇත, ඉන් එකක් ගුප්ත අක්ෂර මාලාවක් වන අතර අනෙක තරමක් අඩු ගුප්ත වාක්‍ය ඛණ්ඩයකි. ක්‍රියාවලියක් මඟින් මතක ආරක්ෂණ නීති කඩන විට ජනනය වන සං signal ාව (සම්මුතිය අනුව) අංක 11 වන අතර, එහි නම් SIGSEGVසහ “ඛණ්ඩනය කිරීමේ දෝෂය” වේ. 5,6 කි

සං als ා සහ බාධා කිරීම් අතර වැදගත් වෙනසක් වන්නේ සෑම සං .ාවක් සඳහාම පෙරනිමි හැසිරීමක් තිබීමයි. සියළුම බාධා කිරීම් සඳහා හසුරුවන්නන් නිර්වචනය කිරීමට මෙහෙයුම් පද්ධතිය අපොහොසත් වුවහොත් එය මෙහෙයුම් පද්ධතියේ දෝෂයකි, තවද CPU අතුරුදහන් වූ හසුරුවන්නෙකු ඉල්ලා සිටීමට උත්සාහ කරන විට මුළු පරිගණකයම බිඳ වැටෙනු ඇත. නමුත් සියලුම සං als ා සඳහා සං hand ා හසුරුවන්නන් අර්ථ දැක්වීමට ක්‍රියාවලීන් බැඳී නොමැත. කර්නලය ක්‍රියාවලියක් සඳහා සං signal ාවක් ජනනය කරන්නේ නම් සහ එම සං signal ාව එහි පෙරනිමි හැසිරීමෙන් ඉතිරි වී ඇත්නම්, කර්නලය ඉදිරියට ගොස් පෙරනිමිය කුමක් කළත් ක්‍රියාවලියට කරදර නොවනු ඇත. බොහෝ සං als ා වල පෙරනිමි හැසිරීම් එක්කෝ "කිසිවක් නොකරන්න" හෝ "මෙම ක්‍රියාවලිය අවසන් කරන අතර සමහර විට මූලික ඩම්ප් එකක් ද නිපදවනු ඇත." SIGSEGVදෙවැන්නකි.

ඉතින්, නැවත බැලීමට, අපට මතක ආරක්ෂණ නීති කඩ කළ ක්‍රියාවලියක් ඇත. CPU විසින් ක්‍රියාවලිය අත්හිටුවා සමමුහුර්ත බාධාවක් ජනනය කළේය. කර්නලය එම බාධා කිරීම් සිදු SIGSEGVකර ක්‍රියාවලිය සඳහා සං signal ාවක් ජනනය කළේය . ක්‍රියාවලිය සං signal ා හසුරුවන්නෙකු සකසා නැතැයි උපකල්පනය කරමු SIGSEGV, එබැවින් කර්නලය පෙරනිමි හැසිරීම සිදු කරයි, එය ක්‍රියාවලිය අවසන් කිරීම වේ. මෙය _exitපද්ධති ඇමතුමට සමාන බලපෑම් ඇති කරයි : විවෘත ලිපිගොනු වසා ඇත, මතකය අවලංගු කර ඇත.

මේ දක්වා කිසිවක් මිනිසෙකුට දැකිය හැකි කිසිදු පණිවිඩයක් මුද්‍රණය කර නොමැති අතර කවචය (හෝ, වඩාත් සාමාන්‍යයෙන්, දැන් අවසන් වී ඇති ක්‍රියාවලියේ මව් ක්‍රියාවලිය ) කිසිසේත් සම්බන්ධ වී නොමැත. SIGSEGVනීති කඩ කළ ක්‍රියාවලියට මිස එහි මවුපියන්ට නොවේ . මෙම ඉදිරි මෙම අනුපිළිවෙල පියවර, නමුත්, තම දරුවන් ළමා අවසන් කර ඇති බව මව් ක්රියාවලිය දැනුවත් කිරීමට ය. මෙම මව් දැනටමත් එක් භාවිතා, මෙම නිවේදනය සඳහා නැවතී ඇත විට සරලතම වන කිහිපයක් විවිධ ක්රම, එය සිදුවිය හැකි ය waitපද්ධතිය ඇමතුම් ( wait, waitpid, wait4, ආදිය). එවැනි අවස්ථාවකදී, කර්නලය මඟින් එම පද්ධතියේ ඇමතුම නැවත ලබා දෙන අතර මව් ක්‍රියාවලියට පිටවීමේ තත්වය යනුවෙන් කේත අංකයක් සපයනු ඇත.. 7 මෙම පිටවීමේ තත්ත්වය මව් දැනුම් ඇයි දරුවා ක්රියාවලිය අවසන් කළ බවත්; මෙම අවස්ථාවේ දී, සං .ාවක පෙරනිමි හැසිරීම හේතුවෙන් දරුවා අවසන් කළ බව ඉගෙන ගනු ඇත SIGSEGV.

දෙමව්පියන්ගේ ක්‍රියාවලිය පණිවිඩයක් මුද්‍රණය කිරීමෙන් සිදුවීම මිනිසෙකුට වාර්තා කළ හැකිය; කවච වැඩසටහන් සෑම විටම පාහේ මෙය කරයි. ඒ සඳහා ඔබේ crshකේතය ඇතුළත් නොවේ, නමුත් එය කෙසේ හෝ සිදු වේ, මන්ද සී පුස්තකාල චර්යාව systemඅංගසම්පූර්ණ කවචයක් ධාවනය කරයි /bin/sh, එනම් “හුඩ් යට”. crshයනු grandparent මෙම තත්වය තුළ, මව්-ක්‍රියාවලි දැනුම්දීම මඟින් /bin/shක්ෂේත්‍රය මඟින් එහි සුපුරුදු පණිවිඩය මුද්‍රණය කරයි. ඊට /bin/shවඩා වැඩි යමක් නැති නිසාත්, සී පුස්තකාලය ක්‍රියාත්මක කිරීමෙන් එම පිටවීමේ දැනුම්දීම systemලැබෙනු ඇත. හි ප්‍රතිලාභ අගය පරීක්ෂා කිරීමෙන් එම පිටවීමේ දැනුම්දීම ඔබේ කේතයේ දැකිය හැකියsystem; නමුත් මුනුබුරාගේ ක්‍රියාවලිය සෙග්ෆෝල්ට් එකකින් මිය ගිය බව එය ඔබට නොකියනු ඇත, මන්ද එය පරිභෝජනය කරනු ලැබුවේ අතරමැදි ෂෙල් ක්‍රියාවලියෙනි.


පාද සටහන්

  1. සමහර මෙහෙයුම් පද්ධති කර්නලයේ කොටසක් ලෙස උපාංග ධාවක ක්‍රියාත්මක නොකරයි ; කෙසේ වෙතත්, සියලු බාදා පේනු තවමත් කර්නලය කොටසක් විය, දෘඪාංග කිසිම දේකට ඉඩ නැති නිසා ඇති ද, එසේ මතක ආරක්ෂාව මාන කරන කේතය කරන්නේ නමුත් මේ දේවල් කිරීමට කර්නලය.

  2. කර්නලයට වඩා වරප්‍රසාද ලත් “හයිපර්වයිසර්” හෝ “අතථ්‍ය යන්ත්‍ර කළමණාකරු” නමින් වැඩසටහනක් තිබිය හැකි නමුත් මෙම පිළිතුරේ අරමුණු සඳහා එය දෘඩාංගයේ කොටසක් ලෙස සැලකිය හැකිය .

  3. කර්නලය වැඩසටහනකි , නමුත් එය ක්‍රියාවලියක් නොවේ ; එය පුස්තකාලයක් වැනි ය. සියළුම ක්‍රියාදාමයන් ඔවුන්ගේ කේතයට අමතරව වරින් වර කර්නල් කේතයේ කොටස් ක්‍රියාත්මක කරයි. කර්නල් කේතය පමණක් ක්‍රියාත්මක කරන "කර්නල් නූල්" ගණනාවක් තිබිය හැකි නමුත් ඒවා මෙහි අප ගැන තැකීමක් නොකරයි.

  4. යුනික්ස් ක්‍රියාත්මක කිරීමක් ලෙස සැලකිය නොහැකි ඔබට තවදුරටත් ගනුදෙනු කිරීමට සිදුවිය හැකි එකම සහ එකම මෙහෙයුම් පද්ධතිය වන්නේ වින්ඩෝස් ය. මෙම තත්වය තුළ එය සං als ා භාවිතා නොකරයි. (ඇත්ත වශයෙන්ම, එය නොවේ ඇති සංඥා; වින්ඩෝස් මත <signal.h>. අතුරු මුහුණත සම්පූර්ණයෙන්ම C පුස්තකයන් විසින් සැකකරු ඇත) එය "ලෙස හඳුන්වන දෙයක් භාවිතා ව්යුහගත හැර කටයුතු " වෙනුවට.

  5. සමහර මතක ආරක්ෂණ උල්ලං lations SIGBUSනයන් වෙනුවට ("බස් දෝෂය") ජනනය කරයි SIGSEGV. මේ දෙක අතර රේඛාව අවිනිශ්චිත වන අතර එය පද්ධතියෙන් පද්ධතියට වෙනස් වේ. ඔබ හසුරුවන්නෙකු නිර්වචනය කරන වැඩසටහනක් ලියා ඇත්නම් SIGSEGV, බොහෝ විට එකම හසුරුවන්නා නිර්වචනය කිරීම හොඳ අදහසකි SIGBUS.

  6. “ඛණ්ඩනය කිරීමේ දෝෂය” යනු මුල් යුනික්ස් ධාවනය කළ එක් පරිගණකයකින් මතක ආරක්ෂණ උල්ලං for නය කිරීම් සඳහා ජනනය කරන ලද බාධකයේ නමයි , බොහෝ විට පීඩීපී -11 . " ඛණ්ඩනය " යනු මතක ආරක්ෂණ වර්ගයකි , නමුත් වර්තමානයේ "ඛණ්ඩනය කිරීමේ දෝෂය " යන වචනය සාමාන්‍යයෙන් ඕනෑම ආකාරයක මතක ආරක්ෂණ උල්ලං to නයකට යොමු කරයි.

  7. දරුවෙකු අවසන් වී ඇති බව දෙමාපිය ක්‍රියාවලියට දැනුම් දිය හැකි අනෙක් සියලු ක්‍රම, දෙමව්පියන් ඇමතීමෙන් waitසහ පිටවීමේ තත්වයක් ලැබීමෙන් අවසන් වේ. පළමුවෙන්ම වෙනත් දෙයක් සිදු වේ.


vzvol: දැන්වීම 2) ක්‍රියාවලි ගැන CPU කිසිවක් නොදන්නා බව පැවසීම නිවැරදි යැයි මම නොසිතමි. එය පාලනය මාරු කරන බාධාකාරී හසුරුවන්නෙකු ඉල්ලා සිටින බව ඔබ පැවසිය යුතුය.
user323094

9
32 user323094 නූතන බහුකාර්ය CPUs ඇත්ත වශයෙන්ම ක්‍රියාවලි ගැන තරමක් දනී; මෙම තත්වය තුළ, ඔවුන්ට මතක-ආරක්ෂණ දෝෂය අවුලුවන ක්‍රියාත්මක කිරීමේ නූල් පමණක් අත්හිටුවිය හැකිය. එසේම, මම උත්සාහ කළේ පහත් මට්ටමේ තොරතුරු ලබා නොගැනීමටයි. පරිශීලක-අභ්‍යවකාශ ක්‍රමලේඛකයාගේ දෘෂ්ටි කෝණයෙන්, 2 වන පියවර ගැන වටහා ගත යුතු වැදගත්ම දෙය නම් මතක ආරක්ෂණය උල්ලං lations නය කිරීම් හඳුනාගන්නා දෘඩාංගය ; අඩු නිසා දෘඩාංග, ස්ථිරාංග සහ මෙහෙයුම් පද්ධතිය අතර ශ්‍රමයේ නිරවද්‍ය බෙදීම “වරදකාරී ක්‍රියාවලිය” හඳුනා ගැනීමේදී.
zwol

බොළඳ පා er කයෙකු ව්‍යාකූල කළ හැකි තවත් සියුම් දෙයක් නම්, "කර්නලය විසින් වැරදි ක්‍රියාවලිය SIGSEGV සං .ාවක් යවයි." එය සුපුරුදු ප්‍රභාෂාව භාවිතා කරයි, නමුත් ඇත්ත වශයෙන්ම අදහස් කරන්නේ ක්‍රියාවලි තීරුවේ සං signal ා foo සමඟ කටයුතු කිරීමට කර්නලය තමාටම කියා ගන්නා බවයි (එනම් සං signal ා හසුරුවන්නෙකු ස්ථාපනය කර නොමැති නම් පරිශීලක කේතය සම්බන්ධ නොවනු ඇත, ප්‍රශ්නය කර්නලය විසින් විසඳනු ලැබේ). එම හේතුව නිසා “ක්‍රියාවලිය පිළිබඳ SIGSEGV සං signal ාවක් මතු කිරීමට මම සමහර විට කැමැත්තෙමි .
dmckee --- හිටපු උපපරිපාලක පූස් පැටවා

2
SIGBUS (බස් දෝෂය) සහ SIGSEGV (ඛණ්ඩනය කිරීමේ දෝෂය) අතර ඇති සැලකිය යුතු වෙනස මෙයයි: SIGSEGV සිදුවන්නේ ඔබ ලිපිනයකට ප්‍රවේශ නොවිය යුතු බව CPU දන්නා විටය (එබැවින් එය බාහිර මතක බස් ඉල්ලීමක් නොකරයි). SIGBUS සිදුවන්නේ CPU විසින් ඔබගේ ඉල්ලීම එහි බාහිර ලිපින බස් රථයට ඇතුළත් කළ පසු පමණි. නිදසුනක් ලෙස, බස් රථයේ කිසිවක් ප්‍රතිචාර නොදක්වන භෞතික ලිපිනයක් ඉල්ලා සිටීම, හෝ වැරදි ලෙස පෙලගැසී ඇති මායිමක දත්ත කියවීමට ඉල්ලා සිටීම (ඒ වෙනුවට ලබා ගැනීමට භෞතික ඉල්ලීම් දෙකක් අවශ්‍ය වේ)
ස්ටුවර්ට් කේයි

2
@ ස්ටුවර්ට්කේයි ඔබ විස්තර කරන්නේ බාධා කිරීම් වල හැසිරීමයි ; ඇත්ත වශයෙන්ම, බොහෝ CPUs ඔබ ගෙනහැර දක්වන වෙනස කරයි (සමහර ඒවා නොතිබුණද, දෙක අතර රේඛාව වෙනස් වේ). මෙම සංඥා SIGSEGV හා SIGBUS, කෙසේ වෙතත්, ඇත නැත විශ්වාසවන්ත කටයුතු ආරංචි මාර්ගවලින් එම CPU මට්ටමේ කොන්දේසි දෙකක් සිතියම් ගත කළහ. SIGSEGV ට වඩා POSIX සඳහා SIGBUS අවශ්‍ය වන එකම කොන්දේසිය වන්නේ ඔබ mmapගොනුවට වඩා විශාල මතක කලාපයකට ගොනුවක් ගෙන ගොනුවේ අවසානයෙන් ඔබ්බට “සම්පූර්ණ පිටු” වෙත ප්‍රවේශ වීමයි. (SIGSEGV / SIGBUS / SIGILL / යනාදිය සිදුවන්නේ කවදාද යන්න පිළිබඳව POSIX වෙනත් ආකාරයකින් අපැහැදිලි ය.)
zwol

42

කවචයට ඇත්ත වශයෙන්ම එම පණිවිඩයට යම් සම්බන්ධයක් ඇති අතර crshවක්‍රව ෂෙල් එකක් අමතයි, එය බොහෝ විට විය හැකිය bash.

මම කුඩා සී වැඩසටහනක් ලිව්වෙමි.

#include <stdio.h>

int
main(int ac, char **av)
{
        int *i = NULL;

        *i = 12;

        return 0;
}

මම එය මගේ සුපුරුදු කවචයෙන් ධාවනය කරන විට zsh, මට මෙය ලැබේ:

4 % ./segv
zsh: 13512 segmentation fault  ./segv

මම එය ක්‍රියාත්මක කරන විට bash, ඔබේ ප්‍රශ්නයේ ඔබ සඳහන් කළ දේ මට ලැබේ:

bediger@flq123:csrc % ./segv
Segmentation fault

මම මගේ කේතයේ සං hand ා හසුරුවන්නෙකු ලිවීමට යන අතර, එවිට මට වැටහී system()ගියේ crshවිධායකයේ ෂෙල් එක භාවිතා කරන පුස්තකාල ඇමතුම /bin/shඅනුව man 3 system. එය /bin/shනිසැකවම පාහේ "බෙදීම් දෝෂය" මුද්‍රණය කරයි crsh.

වැඩසටහන ක්‍රියාත්මක crshකිරීම සඳහා execve()පද්ධති ඇමතුම භාවිතා කිරීම සඳහා ඔබ නැවත ලිවුවහොත්, ඔබට "ඛණ්ඩනය කිරීමේ දෝෂය" නොපෙනේ. එය පැමිණෙන්නේ කවචයෙන් system().


5
මම මේ ගැන සාකච්ඡා කරමින් සිටියේ ඩීට්රිච් එප් සමඟයි. මම ක්‍රෑෂ් අනුවාදයක් එකට හැක් කරexecvp නැවත පරීක්‍ෂණය කළෙමි, ෂෙල් එක තවමත් කඩා වැටෙන්නේ නැති අතර (SIGSEGV කවදාවත් කවචයට යවනු නොලැබේ ), එය "ඛණ්ඩනය කිරීමේ දෝෂය" මුද්‍රණය නොකරයි . කිසිවක් කිසිසේත් මුද්‍රණය නොවේ. මෙයින් පෙනී යන්නේ කවචය එහි ළමා ක්‍රියාවලීන් killed ාතනය වූ විට අනාවරණය වන අතර “ඛණ්ඩනය කිරීමේ දෝෂය” (හෝ එහි යම් ප්‍රභේදයක්) මුද්‍රණය කිරීම සඳහා වගකිව යුතු බවයි.
බ්‍රැඩන් හොඳම

2
Rad බ්‍රැඩන්බෙස්ට් - මම එකම දේ කළා, මගේ කේතය ඔබේ කේතයට වඩා බෑවුම් සහිතයි. මට කිසිසේත් පණිවිඩයක් ලැබුනේ නැත. මම waitpid()එක් එක් දෙබලක / ක්‍රියාත්මක කිරීමේදී භාවිතා කළ අතර, එය 0 තත්වයෙන් පිටවන ක්‍රියාවලීන්ට වඩා, ඛණ්ඩනය කිරීමේ දෝෂයක් ඇති ක්‍රියාවලි සඳහා වෙනස් අගයක් ලබා දෙයි.
ru ස් එඩිගර්

21

"CPU හි MMU සං signal ාවක් යවයි" සහ "කර්නලය එය අවලංගු කිරීමේ වැඩසටහනට යොමු කරයි, එය අවසන් කරයි" හැරෙන්නට මේ පිළිබඳ කිසිදු තොරතුරක් මට සොයාගත නොහැක.

මෙය තරමක සාරාංශයකි. යුනික්ස් සං signal ා යාන්ත්‍රණය ක්‍රියාවලිය ආරම්භ කරන CPU- විශේෂිත සිදුවීම් වලට වඩා සම්පූර්ණයෙන්ම වෙනස් ය.

පොදුවේ ගත් කල, නරක ලිපිනයකට ප්‍රවේශ වූ විට (හෝ කියවීමට පමණක් ඇති ප්‍රදේශයකට ලිවීම, ක්‍රියාත්මක කළ නොහැකි අංශයක් ක්‍රියාත්මක කිරීමට උත්සාහ කිරීම යනාදිය), CPU විසින් යම් CPU- විශේෂිත සිදුවීමක් ජනනය කරනු ඇත (සාම්ප්‍රදායික VM නොවන ගෘහ නිර්මාණ මත මෙය විය එක් එක් "කොටස" (සාම්ප්‍රදායිකව, කියවීමට පමණක් ක්‍රියාත්මක කළ හැකි "පෙළ", ලිවිය හැකි සහ විචල්‍ය-දිග "දත්ත" සහ සාම්ප්‍රදායිකව මතකයේ ප්‍රතිවිරුද්ධ කෙළවරේ ඇති තොගය) ස්ථාවර පරාසයක ලිපින පරාසයක් ඇති බැවින්, එය ඛණ්ඩනය උල්ලං called නය කිරීමක් ලෙස හැඳින්වේ - නවීන ගෘහ නිර්මාණ ශිල්පය මත එය පිටු දෝෂයක් [සිතියම්ගත නොකළ මතකය සඳහා] හෝ ප්‍රවේශ උල්ලං violation නය කිරීමක් [අවසර ප්‍රශ්න කියවීම, ලිවීම සහ ක්‍රියාත්මක කිරීම සඳහා] විය හැකි අතර ඉතිරි පිළිතුර සඳහා මම මේ පිළිබඳව අවධානය යොමු කරමි).

දැන්, මෙම අවස්ථාවේදී, කර්නලයට කරුණු කිහිපයක් කළ හැකිය. වලංගු නමුත් පටවා නැති මතකය සඳහා පිටු දෝෂ ද ජනනය වේ (උදා: මාරු වී ඇත, හෝ සිතියම් ගත කළ ගොනුවක යනාදිය), මේ අවස්ථාවේ දී කර්නලය මතකය සිතියම් ගත කර පරිශීලක වැඩසටහන නැවත ආරම්භ කරයි. දෝෂයකි. එසේ නොමැති නම් එය සං .ාවක් යවයි. සං [ා හසුරුවන්නෙකු ස්ථාපනය කිරීමේ ක්‍රියාවලිය වෙනස් වන අතර බොහෝ දුරට ගෘහ නිර්මාණ ශිල්පයෙන් ස්වාධීන වන බැවින් මෙය හරියටම “මුල් සිදුවීම] වරදකාරී වැඩසටහනට යොමු නොකරයි”.

පරිශීලක වැඩසටහනට සං hand ා හසුරුවන්නෙකු ස්ථාපනය කර ඇත්නම්, මෙයින් අදහස් කරන්නේ තොග රාමුවක් නිර්මාණය කිරීම සහ පරිශීලක වැඩසටහන ක්‍රියාත්මක කිරීමේ ස්ථානය සං hand ා හසුරුවන්නාට සැකසීමයි. සියලුම සං als ා සඳහාද මෙයම සිදු වේ, නමුත් ඛණ්ඩනය උල්ලං of නය කිරීමකදී සාමාන්‍යයෙන් දේවල් පිළිවෙලට තබා ඇති අතර එමඟින් සං hand ා හසුරුවන්නා නැවත පැමිණියහොත් එය දෝෂයට හේතු වූ උපදෙස් නැවත ආරම්භ වේ. පරිශීලක වැඩසටහන මඟින් දෝෂය නිවැරදි කර ඇති අතර, උදා: මතකය වැරදි ලිපිනයට සිතියම් ගත කිරීමෙන් - එය කළ හැකිද යන්න ගෘහ නිර්මාණ ශිල්පය මත රඳා පවතී). සං memory ා හසුරුවන්නාට වැඩසටහනේ වෙනත් ස්ථානයකට පැනිය හැකිය (සාමාන්‍යයෙන් longjmp හරහා හෝ ව්‍යතිරේකයක් විසි කිරීමෙන්), නරක මතක ප්‍රවේශයට හේතු වූ ඕනෑම ක්‍රියාවක් නවතා දැමීමට.

පරිශීලක වැඩසටහනට සං hand ා හසුරුවන්නෙකු ස්ථාපනය කර නොමැති නම්, එය සරලවම අවසන් වේ. සමහර ගෘහ නිර්මාණ වලදී, සං signal ාව නොසලකා හරිනු ලැබුවහොත් එය නැවත නැවතත් උපදෙස් නැවත ආරම්භ කර අනන්ත පුඩුවක් ඇති කරයි.


+1, පිළිගත් පිළිතුරට ඕනෑම දෙයක් එකතු කරන පිළිතුර පමණි. "ඛණ්ඩනය" ඉතිහාසය පිළිබඳ හොඳ විස්තරයක්. විනෝද ඇත්ත: x86 ඇත්තටම තවමත් කොටස සීමාවන් 32bit ආරක්ෂා ආකාරයෙන් (හෝ පිටු සැකසීම තොරව (අථත්ය මතකය) සක්රීය), එසේ ප්රවේශ මතකය ජනනය කළ හැකි උපදෙස් #PF(fault-code)(පිටුව වරදක්) හෝ #GP(0)( "මතක යන අගයද ඵලදායී ලිපිනය, CS පිටත නම් DS, ES, FS, හෝ GS කාණ්ඩයේ සීමාව. "). මෙහෙයුම් පද්ධති වෙනුවට පේජිං භාවිතා කර ඇති නිසාත්, පරිශීලක අවකාශය සඳහා පැතලි මතක ආකෘතියක් ඇති නිසාත් 64bit මාදිලිය කොටස් සීමා කිරීම් පරීක්ෂා කරයි.
පීටර් කෝර්ඩ්ස්

ඇත්ත වශයෙන්ම, x86 හි ඇති බොහෝ මෙහෙයුම් පද්ධතිවල ඛණ්ඩනය කරන ලද පේජින් භාවිතා කරන බව මම විශ්වාස කරමි: පැතලි, පිටු සහිත ලිපින අවකාශයක් තුළ විශාල කොටස් සමූහයක්. එක් එක් ලිපින අවකාශයට ඔබ කර්නල් මතකය ආරක්ෂා කර සිතියම් ගත කරන්නේ එලෙස ය: මුදු (ආරක්ෂණ මට්ටම්) සම්බන්ධ වී ඇත්තේ පිටු වලට නොව කොටස් වලට ය
ලොරෙන්සෝ ඩෙමාට්

එසේම, එන්ටී මත (නමුත් බොහෝ යුනික්ස් වල සමානද යන්න දැන ගැනීමට මම කැමතියි!) “ඛණ්ඩනය කිරීමේ දෝෂය” බොහෝ විට සිදුවිය හැකිය: පරිශීලක අවකාශයේ ආරම්භයේ දී 64k ආරක්ෂිත අංශයක් ඇත, එබැවින් NULL දර්ශකයක් අවලංගු කිරීම a (
නිසිද

1
Ore LorenzoDematté ඔව්, නවීන යුනික්ස් සියල්ලම හෝ ආසන්න වශයෙන් NULL විරූපණයන් හසු කර ගැනීම සඳහා ලිපින අවකාශයේ ආරම්භයේ දී ස්ථිරවම සිතියම් ගත නොකළ ලිපින කැබැල්ලක් තබනු ඇත. එය තරමක් විශාල විය හැකිය - 64-බිට් පද්ධති වල, ඇත්ත වශයෙන්ම එය ගිගාබයිට් හතරක් විය හැකිය , එවිට අහම්බෙන් බිටු 32 දක්වා දර්ශක කපා හැරීම ක්ෂණිකව අල්ලා ගනු ඇත. කෙසේ වෙතත්, දැඩි x86 අර්ථයෙන් බෙදීම කිසිසේත්ම භාවිතා නොවේ; පරිශීලක අවකාශය සඳහා එක් පැතලි ඛණ්ඩයක් සහ කර්නලය සඳහා එකක් ඇත, සමහර විට එෆ්එස් සහ ජීඑස් වලින් යම් ප්‍රයෝජනයක් ලබා ගැනීම වැනි විශේෂ උපක්‍රම සඳහා යුවළක් ඇත.
zwol

1
Ore LorenzoDematté NT සං als ා වලට වඩා ව්‍යතිරේක භාවිතා කරයි; මෙම අවස්ථාවේදී STATUS_ACCESS_VIOLATION.
සසම්භාවී 832

18

ඛණ්ඩනය කිරීමේ දෝෂයක් යනු අවසර නැති මතක ලිපිනයකට ප්‍රවේශ වීමයි (ක්‍රියාවලියේ කොටසක් නොවේ, හෝ කියවීමට පමණක් දත්ත ලිවීමට උත්සාහ කිරීම, හෝ ක්‍රියාත්මක කළ නොහැකි දත්ත ක්‍රියාත්මක කිරීම, ...). මෙය MMU (මතක කළමනාකරණ ඒකකය, අද CPU හි කොටසක්) විසින් අල්ලා ගනු ලැබේ. බාධා කිරීම් හසුරුවනු ලබන්නේ කර්නලය වන අතර, එය වරදක් කිරීමේ ක්‍රියාවලියට සං SIGSEGFAULTsignal ාවක් යවයි ( signal(2)උදාහරණයක් ලෙස බලන්න ). මෙම සං signal ාව සඳහා පෙරනිමි හසුරුවන්නා හරය අතහැර දමයි (බලන්න core(5)) සහ ක්‍රියාවලිය අවසන් කරයි.

කවචයට කිසිසේත්ම අතක් නැත.


7
SIGSEGV හැසිරවිය හැකි / නොසලකා හැරිය හැකි බව ද සඳහන් කිරීම වටී . එබැවින් එය අවසන් නොවන වැඩසටහනක් ලිවිය හැකිය. ජාවා අතථ්‍ය යන්ත්‍රය මෙහි සඳහන් කර ඇති පරිදි විවිධ අරමුණු සඳහා අභ්‍යන්තරව SIGSEGV භාවිතා කරන එක් කැපී පෙනෙන උදාහරණයකි: stackoverflow.com/questions/3731784/…
Karol Nowak

2
ඒ හා සමානව, වින්ඩෝස් හි .NET බොහෝ අවස්ථාවන්හීදී ශුන්‍ය දර්ශක චෙක්පත් එක් කිරීමට කරදර වන්නේ නැත - එය ප්‍රවේශ උල්ලං lations නයන් (සෙග්ෆෝල්ට් වලට සමාන) ලබා ගනී.
user253751
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.