বিভাগের ফল্ট কীভাবে হুডের নীচে কাজ করে?


266

"সিপিইউর এমএমইউ একটি সিগন্যাল প্রেরণ করে" এবং "কার্নেল এটিকে সমাপ্ত করে আপত্তিকর প্রোগ্রামে নির্দেশ দেয়" এর বাইরে আমি এ সম্পর্কিত কোনও তথ্য খুঁজে পাচ্ছি না।

আমি ধরে নিয়েছি এটি সম্ভবত শেলটিতে সংকেত প্রেরণ করে এবং শেলটি আপত্তিকর প্রক্রিয়া এবং মুদ্রণ বন্ধ করে এটি পরিচালনা করে "Segmentation fault"। তাই আমি সেই অনুমানটি পরীক্ষা করেছিলাম একটি চূড়ান্ত নূন্যতম শেল যাকে আমি কল করি ( ক্র্যাপ শেল) কল করে writing এই শেলটি ব্যবহারকারীর ইনপুট নেওয়া এবং এটিকে 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, এক্সটার্ম বন্ধ করবে, খ) মুদ্রণ হবে না "Segmentation fault", অথবা গ) উভয়ই।

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

এক বর্গাকারে ফিরে আসি, আমার ধারণা। আমি কেবল প্রদর্শন করেছি যে এটি শেলটি এটি করে না, তবে সিস্টেমটি নীচে। "সেগমেন্টেশন ফল্ট" কীভাবে মুদ্রিত হয়? "কে" এটা করছে? কর্নেল? অন্যকিছু? সিগন্যাল এবং এর সমস্ত পার্শ্ব প্রতিক্রিয়া কীভাবে হার্ডওয়্যার থেকে প্রোগ্রামের শেষ অবসান পর্যন্ত প্রচার করে?


43
crshএই ধরণের পরীক্ষার জন্য একটি দুর্দান্ত ধারণা। আমাদের সকলকে এটি সম্পর্কে এবং এর পেছনের ধারণাটি জানানোর জন্য ধন্যবাদ।
ব্রুস এডিগার

30
আমি যখন প্রথম দেখেছি crsh, আমি ভেবেছিলাম এটি "ক্রাশ" হিসাবে উচ্চারণ করা হবে। আমি নিশ্চিত না যে এটি একটি সমানভাবে মানানসই নাম কিনা।
jpmc26

56
এটি একটি দুর্দান্ত পরীক্ষা ... তবে আপনার system()হুডের নীচে কী করা উচিত তা আপনার জানা উচিত । দেখা যাচ্ছে যে system()একটি শেল প্রক্রিয়া উত্সাহিত করবে! সুতরাং আপনার শেল প্রক্রিয়াটি অন্য শেল প্রক্রিয়া তৈরি করে এবং সেই শেল প্রক্রিয়া (সম্ভবত /bin/shবা এর মতো কিছু) প্রোগ্রাম চালায়। উপায় /bin/shএবং bashকাজগুলি হ'ল ব্যবহার করে fork()এবং exec()(বা execve()পরিবারের কোনও ফাংশন )।
ডায়েরিচ এপ্প

4
@ ব্র্যাডেনবেস্ট: একদম ঠিক। ম্যানুয়াল পৃষ্ঠাটি পড়ুন man 2 wait, এতে ম্যাক্রোগুলি WIFSIGNALED()এবং অন্তর্ভুক্ত থাকবে WTERMSIG()
ডায়েটারিচ এপ্প

4
আপনি যেমনটি বলেছেন ঠিক তেমনই ডায়েটরিচইপ! আমি (WIFSIGNALED(status) && WTERMSIG(status) == 11)এটি কিছু বোকা ( "YOU DUN GOOFED AND TRIGGERED A SEGFAULT") মুদ্রণ করতে একটি চেক যোগ করার চেষ্টা করেছি । আমি যখন segfaultপ্রোগ্রামটি ভিতর থেকে চালিত করেছি crsh, এটি ঠিক এটি মুদ্রিত হয়েছিল। এদিকে, কমান্ডগুলি যা সাধারণত প্রস্থান হয় ত্রুটি বার্তা উত্পন্ন করে না।
ব্র্যাডেন সেরা

উত্তর:


248

সমস্ত আধুনিক সিপিইউতে বর্তমানে সম্পাদনকারী মেশিনের নির্দেশকে বাধা দেওয়ার ক্ষমতা রয়েছে । তারা পর্যাপ্ত স্থিতি সংরক্ষণ করে (সাধারণত, তবে সর্বদা নয়, স্ট্যাকের উপরে) পরে মৃত্যুদন্ড কার্যকর করা আবার সম্ভব করে তোলে , যেন কিছুই ঘটেছিল না (সাধারণত বাধাপ্রাপ্ত নির্দেশনা স্ক্র্যাচ থেকে পুনরায় শুরু করা হবে)। তারপরে তারা একটি বাধাপ্রাপ্ত হ্যান্ডলারটি কার্যকর করতে শুরু করে , যা কেবলমাত্র আরও মেশিন কোড, তবে একটি বিশেষ স্থানে স্থাপন করা হয় যাতে সিপিইউ জানতে পারে এটি কোথায় রয়েছে। বিঘ্নিত হ্যান্ডলারগুলি সর্বদা অপারেটিং সিস্টেমের কার্নেলের অংশ : এমন উপাদান যা সর্বাধিক অধিকারের সাথে চলে এবং অন্যান্য সমস্ত উপাদানগুলির তদারকির জন্য দায়ী। 1,2

বিঘ্নগুলি সিঙ্ক্রোনাস হতে পারে , এর অর্থ হ'ল সিপিইউ নিজেই সঞ্চালিত নির্দেশাবলীর, বা অ্যাসিনক্রোনাসের কোনও কিছুর প্রত্যক্ষ প্রতিক্রিয়া হিসাবে এটি ট্রিগার করে , মানে বাহ্যিক ইভেন্টের কারণে এগুলি একটি অনাকাঙ্ক্ষিত সময়ে ঘটে, যেমন নেটওয়ার্কে ডেটা আগত like বন্দর। কিছু লোক অবিচ্ছিন্ন বিঘ্নগুলির জন্য "বিঘ্নিত" শব্দটি সংরক্ষণ করে এবং পরিবর্তে সিঙ্ক্রোনাস বিঘ্নকে "ফাঁদ", "ফল্টস", বা "ব্যতিক্রম" বলে ডাকে তবে এই শব্দগুলির সকলের অন্য অর্থ রয়েছে তাই আমি "সংকীর্ণ বিঘ্ন" দিয়ে আটকে যাচ্ছি।

এখন, বেশিরভাগ আধুনিক অপারেটিং সিস্টেমগুলিতে প্রক্রিয়াগুলির ধারণা রয়েছে । একেবারে মৌলিক ক্ষেত্রে, এটি এমন একটি প্রক্রিয়া যার মাধ্যমে কম্পিউটার একই সাথে একাধিক প্রোগ্রাম চালাতে পারে তবে এটি অপারেটিং সিস্টেমগুলি মেমরি সুরক্ষা কীভাবে কনফিগার করে, এটি একটি মূল বিষয় যা বেশিরভাগের বৈশিষ্ট্য (তবে হায়, এখনও সমস্ত নয় ) আধুনিক সিপিইউ। এটি ভার্চুয়াল মেমরির সাথে যায়যা মেমরির ঠিকানা এবং র‌্যামের আসল অবস্থানগুলির মধ্যে ম্যাপিংকে পরিবর্তন করার ক্ষমতা। মেমোরি সুরক্ষা অপারেটিং সিস্টেমটিকে প্রতিটি প্রক্রিয়াটি র‍্যামের নিজস্ব ব্যক্তিগত অংশ দিতে দেয় যা কেবল এটি অ্যাক্সেস করতে পারে। এটি অপারেটিং সিস্টেমকে (কিছু প্রক্রিয়ার পক্ষ থেকে অভিনয় করে) র‌্যামের অঞ্চলগুলি কেবলমাত্র পঠনযোগ্য, সম্পাদনযোগ্য, একাধিক সহযোগী প্রক্রিয়াগুলির মধ্যে ভাগ করে নেওয়া হিসাবে চিহ্নিত করতে সক্ষম করে allows ইত্যাদি মেমরির একটি অংশ থাকবে যা কেবলমাত্র অ্যাক্সেসযোগ্য কার্নেল। 3

যতক্ষণ না প্রতিটি প্রক্রিয়া কেবলমাত্র সেই উপায়ে মেমরি অ্যাক্সেস করে যেভাবে সিপিইউকে অনুমতি দেওয়ার জন্য কনফিগার করা হয়েছে, মেমরির সুরক্ষা অদৃশ্য। যখন কোনও প্রক্রিয়া নিয়মগুলি ভঙ্গ করে, সিপিইউ একটি সিঙ্ক্রোনাস বাধা তৈরি করবে, কার্নেলকে জিনিসগুলি বাছাই করতে বলবে। এটি নিয়মিত ঘটে যে প্রক্রিয়াটি সত্যিই নিয়মগুলি ভঙ্গ করে না , প্রক্রিয়াটি চালিয়ে যাওয়ার অনুমতি দেওয়ার আগে কেবল কার্নেলের কিছু কাজ করা দরকার। উদাহরণস্বরূপ, অন্য কোনও কিছুর জন্য র‌্যামে স্থান ফাঁকা করার জন্য যদি কোনও প্রক্রিয়ার স্মৃতির একটি পৃষ্ঠাকে সোয়াপ ফাইলটিতে "উচ্ছেদ করা" দরকার হয়, কার্নেলটি পৃষ্ঠাটি অ্যাক্সেসযোগ্য হিসাবে চিহ্নিত করবে। পরবর্তী সময় প্রক্রিয়াটি এটি ব্যবহারের চেষ্টা করার পরে, সিপিইউ একটি মেমরি-সুরক্ষা বাধাগুলি উত্পন্ন করবে; কার্নেলটি অদলবদল থেকে পৃষ্ঠাটি পুনরুদ্ধার করবে, এটি যেখানে ছিল সেখানে ফিরে রাখবে, এটিকে আবার অ্যাক্সেসযোগ্য হিসাবে চিহ্নিত করবে এবং পুনরায় প্রয়োগ শুরু করবে।

তবে ধরুন যে প্রক্রিয়াটি সত্যিই নিয়মগুলি ভঙ্গ করেছে। এটি এমন কোনও পৃষ্ঠায় অ্যাক্সেস করার চেষ্টা করেছিল যা এর সাথে কোনও র‌্যাম ম্যাপ করা হয়নি, বা এটি এমন কোনও পৃষ্ঠা কার্যকর করার চেষ্টা করেছে যা মেশিন কোড বা যা কিছু নয় তা চিহ্নিত করা হয়েছে। সাধারণত "ইউনিক্স" নামে পরিচিত অপারেটিং সিস্টেমগুলির পরিবার এই পরিস্থিতিটি মোকাবেলায় সমস্ত সংকেত ব্যবহার করে । 4 সিগন্যালগুলি বিঘ্নের অনুরূপ, তবে এগুলি কার্নেল দ্বারা উত্পাদিত হয় এবং প্রসেস দ্বারা ফিল্ড করা হয়, হার্ডওয়ার দ্বারা উত্পন্ন না করে এবং কার্নেল দ্বারা ফিল্ড করা হয়। প্রক্রিয়া সংকেত হ্যান্ডলার সংজ্ঞায়িত করতে পারেতাদের নিজস্ব কোডে এবং কার্নেলটি তারা কোথায় তা বলুন। তারপরে এই সংকেত হ্যান্ডলারগুলি কার্যকর হওয়ার পরে নিয়ন্ত্রণের স্বাভাবিক প্রবাহকে বাধাগ্রস্ত করবে। সিগন্যালের সকলের একটি সংখ্যা এবং দুটি নাম রয়েছে, যার একটি হ'ল একটি ক্রিপ্টিক সংক্ষিপ্ত বিবরণ এবং অন্যটি কিছুটা কম ক্রিপ্টিক বাক্যাংশ। প্রক্রিয়াটি মেমোরি-সুরক্ষা নিয়মগুলি ভেঙে যখন সংকেত তৈরি হয় তা হ'ল 11 (নাম দ্বারা) এবং এর নামগুলি SIGSEGVএবং "বিভাগকরণ ত্রুটি"। 5,6

সংকেত এবং বিঘ্নের মধ্যে একটি গুরুত্বপূর্ণ পার্থক্য হ'ল প্রতিটি সংকেতের জন্য একটি ডিফল্ট আচরণ থাকে । যদি অপারেটিং সিস্টেমটি সমস্ত বিঘ্নগুলির জন্য হ্যান্ডলারগুলি সংজ্ঞায়িত করতে ব্যর্থ হয়, তবে এটি ওএসের একটি বাগ, এবং সিপিইউ অনুপস্থিত হ্যান্ডলারটি চাওয়ার চেষ্টা করলে পুরো কম্পিউটারটি ক্র্যাশ হয়ে যায়। সমস্ত প্রক্রিয়াগুলির জন্য সংকেত হ্যান্ডলারগুলি সংজ্ঞায়িত করার প্রক্রিয়াগুলির কোনও বাধ্যবাধকতা নেই। কার্নেল যদি কোনও প্রক্রিয়াটির জন্য একটি সংকেত উত্পন্ন করে এবং সেই সংকেতটি তার ডিফল্ট আচরণে রেখে দেওয়া হয়, কার্নেলটি কেবল এগিয়ে যাবে এবং ডিফল্ট যা কিছু করবে তা প্রক্রিয়াটিকে বিরক্ত করবে না। বেশিরভাগ সিগন্যালের ডিফল্ট আচরণগুলি হয় "কিছুই না করে" বা "এই প্রক্রিয়াটি শেষ করে এবং সম্ভবত একটি কোর ডাম্পও উত্পাদন করে।" SIGSEGVপরের এক।

সুতরাং, পুনরুদ্ধার করার জন্য, আমাদের একটি প্রক্রিয়া রয়েছে যা মেমরির সুরক্ষা নিয়মগুলিকে ভেঙে দেয়। সিপিইউ প্রক্রিয়াটি স্থগিত করেছে এবং একটি সিঙ্ক্রোনাস বাধা তৈরি করেছে। কার্নেল ক্ষেত্রের মধ্যে ফেলেছিল এবং SIGSEGVপ্রক্রিয়াটির জন্য একটি সংকেত জেনারেট করে। প্রক্রিয়াকে হয়নি জেনে নিই না জন্য একটি সংকেত হ্যান্ডলার সেট আপ SIGSEGV, তাই কার্নেল ডিফল্ট আচরণ, প্রক্রিয়া বিনষ্ট যা আউট বহন করে। এটি _exitসিস্টেম কলের মতো একই প্রভাব ফেলে : খোলা ফাইলগুলি বন্ধ থাকে, মেমরিটি হ্রাস করা হয় না ইত্যাদি etc.

এই অবধি অবধি কোনও মানুষ কোনও বার্তা মুদ্রণ করতে পারেনি এবং শেলটি (বা আরও সাধারণভাবে, প্রক্রিয়াটির মূল প্রক্রিয়া যা সবে শেষ হয়ে গেছে) মোটেই জড়িত হয়নি। SIGSEGVপ্রক্রিয়া যা নিয়ম ভেঙে যায় না তার পিতা বা মাতা। পরবর্তী ক্রমানুসারে পদক্ষেপ, যদিও, পিতা বা মাতা প্রক্রিয়া যে তার সন্তান বন্ধ করা হয়েছে অবহিত হয়। এই বিভিন্নরূপে, যার মধ্যে সবচেয়ে সহজ যখন পিতা বা মাতা ইতিমধ্যে এই বিজ্ঞপ্তির জন্য অপেক্ষা করছে, এক ব্যবহারে ঘটতে পারে waitসিস্টেম কল ( wait, waitpid, wait4, ইত্যাদি)। সেক্ষেত্রে কার্নেলটি কেবলমাত্র সেই সিস্টেম কলটি ফিরে আসবে এবং প্রস্থান প্রক্রিয়াটিকে একটি প্রস্থান স্থিতি নামক একটি কোড নম্বর দিয়ে সরবরাহ করবে parent7 প্রস্থান স্থিতি সন্তানের প্রক্রিয়াটি কেন সমাপ্ত হয়েছিল তা পিতামাতাকে অবহিত করে ; এই ক্ষেত্রে, এটি শিখবে যে একটি SIGSEGVসংকেতের ডিফল্ট আচরণের কারণে শিশুটিকে সমাপ্ত করা হয়েছিল ।

অভিভাবক প্রক্রিয়া তারপরে একটি বার্তা প্রিন্ট করে ইভেন্টটিকে কোনও মানুষের কাছে রিপোর্ট করতে পারে; শেল প্রোগ্রামগুলি প্রায়শই এটি করে। তোমার crshযে কাজ করতে কোড অন্তর্ভুক্ত করে না, কিন্তু তবুও এটি ঘটে, কারণ সি গ্রন্থাগার রুটিন systemএকটি পূর্ণ-বৈশিষ্ট্যযুক্ত শেল, রান /bin/sh, "ফণা অধীন"। crshএই দৃশ্যে দাদু বাবা ; অভিভাবক-প্রক্রিয়া বিজ্ঞপ্তি দ্বারা ক্ষেত্রযুক্ত /bin/sh, যা এটির স্বাভাবিক বার্তা প্রিন্ট করে। তারপরে /bin/shনিজেই বের হয়ে যায়, কারণ এর আরও কিছু করার নেই এবং সি লাইব্রেরির প্রয়োগটি সেই প্রস্থান বিজ্ঞপ্তিটি systemগ্রহণ করে । এর কোডের রিটার্ন মানটি পরীক্ষা করে আপনি এই কোডটিতে প্রস্থান বিজ্ঞপ্তিটি দেখতে পাচ্ছেনsystem; তবে এটি আপনাকে বলবে না যে নাতি-নাতনি প্রক্রিয়াটি সেগফল্টে মারা গিয়েছিল, কারণ এটি মধ্যবর্তী শেল প্রক্রিয়া দ্বারা গ্রাস করা হয়েছিল।


পাদটিকা

  1. কিছু অপারেটিং সিস্টেম কার্নেলের অংশ হিসাবে ডিভাইস ড্রাইভারগুলি প্রয়োগ করে না ; যাইহোক, সমস্ত বিঘ্নিত হ্যান্ডলারের এখনও কার্নেলের অংশ হতে হবে এবং মেমোরি সুরক্ষা কনফিগার করে এমন কোডটিও রয়েছে কারণ হার্ডওয়্যার কার্নেল ছাড়া আর কিছু করার অনুমতি দেয় না ।

  2. "হাইপারভাইজার" বা "ভার্চুয়াল মেশিন ম্যানেজার" নামে একটি প্রোগ্রাম থাকতে পারে যা কার্নেলের চেয়ে আরও বেশি সুবিধাজনক, তবে এই উত্তরের উদ্দেশ্যে এটি হার্ডওয়ারের অংশ হিসাবে বিবেচনা করা যেতে পারে ।

  3. কার্নেল একটি হল প্রোগ্রাম , কিন্তু এটা না একটি প্রক্রিয়া; এটি আরও একটি লাইব্রেরির মতো। সমস্ত প্রক্রিয়াগুলি নিজের কোড ছাড়াও সময়ে সময়ে কার্নেলের কোডের অংশগুলি কার্যকর করে। অনেকগুলি "কর্নেল থ্রেড" থাকতে পারে যা কেবল কার্নেল কোড চালায়, তবে তারা আমাদের এখানে উদ্বিগ্ন করে না।

  4. ইউনিক্সের বাস্তবায়ন হিসাবে বিবেচনা করা যায় না এমন একমাত্র ওএস আপনাকে সম্ভবত মোকাবেলা করতে হবে যা অবশ্যই উইন্ডোজ। এটি এই পরিস্থিতিতে সংকেত ব্যবহার করে না। (প্রকৃতপক্ষে, এটা না আছে সংকেত; Windows এ <signal.h>ইন্টারফেস সম্পূর্ণরূপে C লাইব্রেরি দ্বারা ছদ্ম হয়।) এটা কিছু "বলা ব্যবহার কাঠামোগত ব্যতিক্রম হ্যান্ডলিং " এর পরিবর্তে।

  5. কিছু স্মৃতি-সুরক্ষা লঙ্ঘন এর SIGBUSপরিবর্তে ("বাসের ত্রুটি") উত্পন্ন করে SIGSEGV। দুজনের মধ্যে লাইনটি অপ্রকাশিত এবং সিস্টেম থেকে সিস্টেমের মধ্যে পরিবর্তিত হয়। যদি আপনি এমন কোনও প্রোগ্রাম লিখেছেন যা হ্যান্ডলারটি সংজ্ঞায়িত করে SIGSEGV, তবে সম্ভবত এটির জন্য একই হ্যান্ডলারের সংজ্ঞা দেওয়া ভাল ধারণা SIGBUS

  6. "সেগমেন্টেশন ফল্ট" কম্পিউটার দৌড়ে এক দ্বারা মেমরি সুরক্ষা লঙ্ঘনের জন্য উত্পন্ন বিঘ্ন নাম ছিলো মূল ইউনিক্স , সম্ভবত পিডিপি -11 । " সেগমেন্টেশন " এক প্রকারের মেমরি সুরক্ষা, তবে আজকাল "সেগমেন্টেশন ফল্ট " শব্দটি যেকোন ধরণের মেমরি সুরক্ষা লঙ্ঘনকে উদারভাবে বোঝায়।

  7. অন্য যে কোনও উপায়ে পিতামাতার প্রক্রিয়াটি কোনও সন্তানের সমাপ্ত হওয়ার বিষয়ে অবহিত হতে পারে, পিতামাতার সাথে কথা বলা waitএবং প্রস্থান স্থিতি অর্জন সমাপ্ত হয় । এটি ঠিক যে আগে অন্য কিছু ঘটে।


@zvol: বিজ্ঞাপন 2) সিপিইউ প্রক্রিয়া সম্পর্কে কিছু জানে বলে আমি এটা বলা ঠিক মনে করি না। আপনার বলা উচিত যে এটি একটি বাধা হ্যান্ডলারকে আহ্বান করে, যা নিয়ন্ত্রণ স্থানান্তর করে।
ব্যবহারকারী 323094

9
@ ব্যবহারকারী 323094 আধুনিক মাল্টিকোর সিপিইউগুলি প্রক্রিয়াগুলি সম্পর্কে আসলে কিছুটা জানেন know পর্যাপ্ত পরিমাণে যাতে, এই পরিস্থিতিতে তারা কেবল মৃত্যুদণ্ড কার্যকর করার থ্রেড স্থগিত করতে পারে যা মেমোরি-সুরক্ষা দোষকে ট্রিগার করে। এছাড়াও, আমি নিম্ন-স্তরের বিশদে না যাওয়ার চেষ্টা করছিলাম। ব্যবহারকারীর স্পেস প্রোগ্রামারের দৃষ্টিকোণ থেকে, পদক্ষেপ 2 সম্পর্কে সবচেয়ে গুরুত্বপূর্ণ বিষয়টি হ'ল এটি সেই হার্ডওয়্যার যা মেমরির সুরক্ষা লঙ্ঘন সনাক্ত করে; "আপত্তিকর প্রক্রিয়া" চিহ্নিত করার ক্ষেত্রে হার্ডওয়ার, ফার্মওয়্যার এবং অপারেটিং সিস্টেমের মধ্যে শ্রমের সুনির্দিষ্ট বিভাজন কম হয়।
zwol

আরেকটি সূক্ষ্মতা যা কোনও নিরীহ পাঠককে বিভ্রান্ত করতে পারে " হ'ল কর্নেল আপত্তিকর প্রক্রিয়াটি একটি SIGSEGV সংকেত প্রেরণ করে।" যা সাধারণ জারগন ব্যবহার করে, তবে প্রকৃত অর্থ হ'ল কার্নেল নিজেকে প্রক্রিয়া বারে সিগন্যাল ফু নিয়ে কাজ করতে বলে ie আমি একযোগে "প্রসেসে একটি SIGSEGV সিগন্যাল উত্থাপন করি " পছন্দ করি ।
ডিএমকেকে

2
SIGBUS (বাস ত্রুটি) এবং SIGSEGV (সেগমেন্টেশন ফল্ট) মধ্যে গুরুত্বপূর্ণ পার্থক্য হল: SIGSEGV ঘটে যখন CPU- র জানেন আপনি একটি ঠিকানা অ্যাক্সেস করা যাবে না (এবং তাই এটি কোন বাইরের মেমরি বাস অনুরোধ করতে না)। সিগাবু তখনই ঘটে যখন সিপিইউ কেবলমাত্র তার বাহ্যিক ঠিকানা বাসে আপনার অনুরোধটি রাখার পরে ঠিকানার সমস্যাটি সম্পর্কে জানতে পারে। উদাহরণস্বরূপ, কোনও শারীরিক ঠিকানা জিজ্ঞাসা করা যার দিকে বাসের কিছুই প্রতিক্রিয়া জানায় না, বা একটি ভুল-সংযুক্ত সীমানায় (যার পরিবর্তে দুটি শারীরিক অনুরোধের প্রয়োজন হবে) সম্পর্কিত ডেটা পড়তে জিজ্ঞাসা করা হয়েছে
স্টুয়ার্ট Caie

2
@ স্টুয়ার্টকায়ে আপনি বাধা ব্যবহারের আচরণ বর্ণনা করছেন ; প্রকৃতপক্ষে, অনেকগুলি সিপিইউ আপনার বাহ্যরেখাটি আলাদা করে দেয় (যদিও কিছু না, এবং উভয়ের মধ্যে লাইন পরিবর্তিত হয়)। সংকেত SIGSEGV এবং SIGBUS অবশ্য হয় না নির্ভরযোগ্যভাবে ঐ দুই CPU- র পর্যায়ের শর্ত মানচিত্র তৈরী করেন। POSIX- এর চেয়ে একমাত্র শর্ত যেখানে SIGSEGV এর চেয়ে SIGBUS প্রয়োজন যখন আপনি যখন mmapকোনও ফাইল ফাইলের চেয়ে বড় মেমরি অঞ্চলে যান এবং তারপরে ফাইলটির শেষের বাইরে "পুরো পৃষ্ঠাগুলি" অ্যাক্সেস করেন। (
সিগসিইজিভি

42

শেলটির প্রকৃতপক্ষে সেই বার্তার সাথে কিছু করার আছে এবং crshঅপ্রত্যক্ষভাবে একটি শেল কল করে যা সম্ভবত bash

আমি একটি ছোট সি প্রোগ্রাম লিখেছিলাম যা সবসময় ত্রুটিগুলি seg করে:

#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

আমি আমার কোডে একটি সিগন্যাল হ্যান্ডলার লিখতে যাচ্ছি, তখন আমি বুঝতে পারি যে এক্সিকিউটিভের system()দ্বারা ব্যবহৃত লাইব্রেরি কলটি crshশেল এর /bin/shমতে man 3 system। যে /bin/shপ্রায় অবশ্যই, "সেগমেন্টেশন ফল্ট" মুদ্রণ যেহেতু হয় crshঅবশ্যই নয়।

আপনি যদি প্রোগ্রামটি চালনার জন্য সিস্টেম কলটি crshব্যবহার করতে পুনরায় লিখেন execve(), আপনি "বিভাগে ফালতু" স্ট্রিংটি দেখতে পাবেন না। এটি দ্বারা চালিত শেল থেকে আসে system()


5
আমি কেবল ডায়েটারিচ এপ্পের সাথে এটি নিয়ে আলোচনা করছিলাম। আমি ক্রশের এমন একটি সংস্করণ একসাথে হ্যাক করেছি execvpযা শেলটি এখনও ক্র্যাশ করে না (যদিও SIGSEGV কখনই শেলের কাছে প্রেরণ করা হয় না), এটি "সেগমেন্টেশন ফল্ট" মুদ্রণ করে না তা খুঁজে বার করার জন্য আবার পরীক্ষা করেছিলাম । কিছুতেই ছাপা হয় না। এটি সূচিত করে মনে হয় যে শেলটি সনাক্ত করে যখন তার শিশু প্রক্রিয়াটি মারা যায় এবং "সেগমেন্টেশন ফল্ট" (বা এর কিছু বৈকল্পিক) মুদ্রণের জন্য দায়বদ্ধ।
ব্র্যাডেন বেস্ট

2
@ ব্র্যাডেনবেস্ট - আমিও একই কাজ করেছি, আমার কোডটি আপনার কোডের চেয়ে opালু। আমি মোটেই কোনও বার্তা পাইনি, এবং আমার এমনকি ক্র্যাপিয়ার শেলও কোনও জিনিস মুদ্রণ করে না। আমি waitpid()প্রতিটি কাঁটাচামচ / এক্সিকিউটে ব্যবহার করেছি এবং এটি 0 স্ট্যাটাসের সাথে প্রস্থান হওয়া প্রসেসের চেয়ে পৃথকীকরণ ত্রুটিযুক্ত প্রসেসের জন্য আলাদা মান দেয়।
ব্রুস এডিগার

21

"সিপিইউর এমএমইউ একটি সিগন্যাল প্রেরণ করে" এবং "কার্নেল এটিকে সমাপ্ত করে আপত্তিকর প্রোগ্রামে নির্দেশ দেয়" এর বাইরে আমি এ সম্পর্কিত কোনও তথ্য খুঁজে পাচ্ছি না।

এটি একটি গার্ল্ড সারাংশ কিছুটা। ইউনিক্স সিগন্যাল প্রক্রিয়াটি সিপিইউ-নির্দিষ্ট ইভেন্টগুলি থেকে প্রক্রিয়া শুরু করা থেকে সম্পূর্ণ পৃথক।

সাধারণভাবে, যখন কোনও খারাপ ঠিকানা অ্যাক্সেস করা হয় (বা কেবলমাত্র পঠনযোগ্য অঞ্চলে লিখিত হয়, অ-কার্যকরযোগ্য বিভাগ সম্পাদন করার চেষ্টা করা হয় ইত্যাদি), সিপিইউ কিছু সিপিইউ-নির্দিষ্ট ইভেন্ট উত্পন্ন করবে (প্রচলিত নন-ভিএম আর্কিটেকচারে এটি ছিল) এক বিভাগকে লঙ্ঘন বলা হয়, যেহেতু প্রতিটি "বিভাগ" (allyতিহ্যগতভাবে, কেবলমাত্র পঠনযোগ্য এক্সিকিউটেবল "পাঠ্য", লিখনযোগ্য এবং পরিবর্তনশীল দৈর্ঘ্যের "ডেটা" এবং স্মৃতিটির বিপরীত প্রান্তে traditionতিহ্যবাহী স্ট্যাকের) ঠিকানার নির্দিষ্ট পরিসীমা ছিল - একটি আধুনিক স্থাপত্যে এটি পৃষ্ঠার ত্রুটি [আনম্যাপড মেমরির জন্য] বা অ্যাক্সেস লঙ্ঘন হওয়ার সম্ভাবনা রয়েছে [পড়ার জন্য, লেখার জন্য এবং অনুমতি সম্পর্কিত সমস্যাগুলি কার্যকর করার জন্য], এবং আমি উত্তরটির বাকি অংশে এটিতে মনোনিবেশ করব)।

এখন, এই মুহুর্তে, কার্নেল বিভিন্ন কাজ করতে পারে। পৃষ্ঠা ত্রুটিগুলি মেমরির জন্যও তৈরি করা হয় যা বৈধ তবে লোড হয়নি (উদাহরণস্বরূপ অদলবদল করা, অথবা একটি এমএম্যাপ করা ফাইল ইত্যাদিতে), এবং এই ক্ষেত্রে কার্নেলটি মেমরিটিকে মানচিত্র তৈরি করবে এবং তারপরে যে নির্দেশনাটি সৃষ্টি হয়েছিল তা থেকে ব্যবহারকারী প্রোগ্রামটি পুনরায় চালু করবে ত্রুটি। অন্যথায়, এটি একটি সংকেত প্রেরণ করে। এটি ঠিক "আসল ঘটনা [মূল ঘটনাটিকে" আপত্তিকর প্রোগ্রামে সরাসরি পরিচালনা করে না ", যেহেতু সিগন্যাল হ্যান্ডলারটি ইনস্টল করার প্রক্রিয়াটি ভিন্ন এবং বেশিরভাগই আর্কিটেকচার-ইন্ডিপেন্ডেন্ট, বনাম, যদি কোনও বিঘ্নিত হ্যান্ডলার ইনস্টল করার অনুকরণটি আশা করা হত।

যদি ব্যবহারকারী প্রোগ্রামটিতে একটি সিগন্যাল হ্যান্ডলার ইনস্টল থাকে তবে এর অর্থ একটি স্ট্যাক ফ্রেম তৈরি করা এবং ব্যবহারকারীর প্রোগ্রামের নির্বাহের অবস্থানটি সিগন্যাল হ্যান্ডলারের সাথে সেট করা। সমস্ত সিগন্যালের ক্ষেত্রেও একই কাজ করা হয় তবে বিভাগগুলির লঙ্ঘনের ক্ষেত্রে সাধারণত জিনিসগুলি সাজানো হয় যাতে সিগন্যাল হ্যান্ডলারটি ফিরে আসে তা ত্রুটির কারণ হিসাবে নির্দেশনা পুনরায় চালু করে। ব্যবহারকারী প্রোগ্রামটি ত্রুটিটি সমাধান করে থাকতে পারে, যেমন আপত্তিজনক ঠিকানায় মেমরি ম্যাপ করে - এটি সম্ভব কিনা তা আর্কিটেকচার নির্ভর। সংকেত হ্যান্ডলার প্রোগ্রামটির ভিন্ন স্থানেও যেতে পারে (সাধারণত লংজ্যাম্পের মাধ্যমে বা একটি ব্যতিক্রম ছুঁড়ে দিয়ে), যে কোনও অপারেশন খারাপ স্মৃতি অ্যাক্সেসের কারণ হতে পারে ab

যদি ব্যবহারকারী প্রোগ্রামটিতে সিগন্যাল হ্যান্ডলার ইনস্টল না থাকে, তবে এটি সহজভাবে বন্ধ করা হয়। কিছু আর্কিটেকচারে, যদি সংকেতটি উপেক্ষা করা হয় তবে এটি নির্দেশটি বারবার চালু করতে পারে এবং অসীম লুপের কারণ হতে পারে।


+1, কেবলমাত্র এমন উত্তর যা গ্রহণযোগ্যটির সাথে কিছু যোগ করে। "বিভাজন" ইতিহাসের দুর্দান্ত বর্ণনা। মজাদার ঘটনা: x86 এর এখনও অবধি 32 বিট সুরক্ষিত মোডে বিভাগের সীমা রয়েছে (পেজিং সহ বা না ছাড়াই (ভার্চুয়াল মেমরি) সক্ষম করা আছে), সুতরাং যে নির্দেশাবলী অ্যাক্সেস মেমরিটি #PF(fault-code)(পৃষ্ঠা ত্রুটি) উত্পন্ন করতে পারে বা #GP(0)"যদি কোনও মেমরি অপারেণ্ড কার্যকর ঠিকানা সিএসের বাইরে থাকে, ডিএস, ইএস, এফএস, বা জিএস বিভাগের সীমা "")। Bit৪ বিট মোড সেগমেন্ট সীমা পরীক্ষা করে ফেলেছে, যেহেতু ওএস এর পরিবর্তে কেবল পেজিং ব্যবহার করেছে এবং ব্যবহারকারী-স্থানের জন্য একটি সমতল মেমরির মডেল।
পিটার কর্ডেস

প্রকৃতপক্ষে, আমি বিশ্বাস করি যে x86 এর বেশিরভাগ ওএসগুলি বিভাগিত পৃষ্ঠাগুলি ব্যবহার করে: একটি ফ্ল্যাট, পৃষ্ঠাযুক্ত ঠিকানার জায়গার অভ্যন্তরে একগুচ্ছ বড় অংশ। আপনি প্রতিটি ঠিকানার
জায়গাতে কার্নেল মেমরিটিকে এভাবে

এছাড়াও, এনটি-তে (তবে আমি জানতে চাই যে বেশিরভাগ ইউনিক্সে একই হয় কিনা!) "সেগমেন্টেশন ফল্ট" প্রায়শই ঘটতে পারে: ব্যবহারকারীর স্পেসের শুরুতে একটি k৪ কে সুরক্ষিত বিভাগ রয়েছে, সুতরাং একটি NULL পয়েন্টারকে ডিফারেন্সিং একটি উত্থাপন করে (যথাযথ?) বিভাজন ত্রুটি
লরেঞ্জো ডিম্যাটmat

1
@ লোরেঞ্জো ডিমেটé হ্যাঁ, সমস্ত বা প্রায় সমস্ত আধুনিক ইউনিক্সগুলি NUL ডিসেরেন্সগুলি ধরার জন্য ঠিকানার জায়গার শুরুতে স্থায়ীভাবে আনম্যাপ করা ঠিকানার একটি অংশ ছেড়ে যাবে। এটি বেশ বড় হতে পারে - 64৪-বিট সিস্টেমে, এটি চার গিগাবাইট হতে পারে , যাতে 32 বিটের মধ্যে পয়েন্টারগুলির দুর্ঘটনাক্রমে কাটানো অবিলম্বে ধরা পড়বে। তবে, কঠোর x86 অর্থে বিভাজন সবেমাত্র ব্যবহৃত হয়; ব্যবহারকারীর স্পেসের জন্য একটি সমতল বিভাগ এবং কার্নেলের জন্য একটি এবং সম্ভবত বিশেষ কৌশলগুলির জন্য একটি দম্পতি এফএস এবং জিএস থেকে কিছুটা ব্যবহার পাওয়ার মতো রয়েছে।
zwol

1
@ LorenzoDematté এনটি সিগন্যালের চেয়ে ব্যতিক্রম ব্যবহার করে; এই ক্ষেত্রে STATUS_ACCESS_VIOLATION ATION
র্যান্ডম 832

18

সেগমেন্টেশন ত্রুটি হ'ল মেমোরি ঠিকানার অ্যাক্সেস যা অনুমোদিত নয় (প্রক্রিয়াটির অংশ নয়, বা কেবল পঠনযোগ্য ডেটা লেখার চেষ্টা করছে, বা অ-এক্সিকিউটেবল ডেটা কার্যকর করতে পারে ...)। এটি এমএমইউ দ্বারা ধরা পড়েছে (মেমরি ম্যানেজমেন্ট ইউনিট, আজ সিপিইউর অংশ), একটি বাধা সৃষ্টি করে causing বাধাটি কার্নেল দ্বারা পরিচালিত হয়, যা আপত্তিজনক প্রক্রিয়াতে একটি SIGSEGFAULTসংকেত ( signal(2)উদাহরণস্বরূপ) প্রেরণ করে। এই সিগন্যালের জন্য ডিফল্ট হ্যান্ডলারটি মূল (দেখুন core(5)) ডাম্প করে এবং প্রক্রিয়াটি সমাপ্ত করে।

শেলটির একেবারেই কোনও হাত নেই।


3
সুতরাং আপনার সি লাইব্রেরি, একটি ডেস্কটপে glibc মত স্ট্রিং সংজ্ঞায়িত?
ড্র্রুবেন

7
এরও কোন মূল্য নেই যে SIGSEGV মূল্য পারেন পরিচালনা করা / উপেক্ষা করেছেন। সুতরাং এমন কোনও প্রোগ্রাম লেখা সম্ভব যা এটির মাধ্যমে শেষ হয় না। জাভা ভার্চুয়াল মেশিন একটি উল্লেখযোগ্য উদাহরণ যা এখানে সিএসসিইজিভি
করোল নওক

2
অনুরূপভাবে, উইন্ডোজে .NET বেশিরভাগ ক্ষেত্রে নাল পয়েন্টার চেক যোগ করা বিরক্ত করে না - এটি কেবল অ্যাক্সেস লঙ্ঘনগুলি (সেগফাল্টসের সমতুল্য) ধরা দেয়।
ইমিগ্রিস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.