কার্যকর করার সময় বাইনারি পরিবর্তন করা হচ্ছে


10

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

তবে, বলুন a.outএকটি বিশাল ফাইল ছিল, র‌্যামের আকারের সাথে তুলনামূলক ble এক্ষেত্রে কী হবে? এবং বলুন এটি কোনও ভাগ করা অবজেক্ট ফাইলে লিঙ্ক হয়েছে libblas.so, যদি আমি libblas.soরানটাইমের সময় সংশোধন করি ? কি হবে?

আমার মূল প্রশ্নটি হ'ল - ওএস কি গ্যারান্টি দেয় যে আমি যখন চলি a.outতখন মূল বাইনারি অনুসারে মূল কোডটি সর্বদা স্বাভাবিকভাবে চলবে .so, তার সাথে যুক্ত ফাইলগুলি .oএবং .soফাইলগুলি সংযুক্ত হওয়া সত্ত্বেও, তার ফাইলগুলি বা লিঙ্কগুলির সাথে লিঙ্ক করে না রানটাইম?

আমি জানি যে এখানে এই জাতীয় প্রশ্নগুলি রয়েছে যা একই ধরণের সমস্যাগুলি দেখায় : https://stackoverflow.com -at-একবার আপনি যদি সম্পাদনার সময় কোনও স্ক্রিপ্ট সম্পাদনা করেন? কোনও প্রোগ্রাম চলাকালীন লাইভ আপডেট করা কীভাবে সম্ভব?

যা আমাকে এ সম্পর্কে আরও কিছুটা বুঝতে সাহায্য করেছে তবে আমি মনে করি না যে তারা ঠিক কী চাইছে তা আমি জিজ্ঞাসা করছি যা কার্যকর হওয়ার সময় বাইনারি সংশোধন করার পরিণতিগুলির জন্য একটি সাধারণ নিয়ম


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

@ জন ডাব্লুএইচএসমিথ অন স্ট্যাকওভারফ্লোতে, শীর্ষ উত্তরটি বলেছে if they are read-only copies of something already on disc (like an executable, or a shared object file), they just get de-allocated and are reloaded from their source, তাই আমি এই ধারণাটি পেয়েছি যে যদি আপনার বাইনারিটি বিশাল হয় তবে যদি আপনার বাইনারিটির কিছু অংশ র‌্যামের বাইরে চলে যায় তবে আবার প্রয়োজন হয় তবে এটি "উত্স থেকে পুনরায় লোড করা হয়েছে" - যাতে কোনও পরিবর্তন হয় .(s)oফাইল সম্পাদনের সময় প্রতিফলিত হবে। তবে অবশ্যই আমার ভুল বোঝাবুঝি হতে পারে - এ কারণেই আমি এই আরও নির্দিষ্ট প্রশ্ন জিজ্ঞাসা করছি
টেক্সাসফ্লাড

@ জন ডাব্লুএইচএসমিথ এছাড়াও দ্বিতীয় উত্তরটি বলেছে No, it only loads the necessary pages into memory. This is demand paging.তাই আমি আসলে এই ধারণার মধ্যে ছিলাম যে আমি যা চেয়েছি তার নিশ্চয়তা দেওয়া যায় না।
টেক্সাসফ্লুড

উত্তর:


11

স্ট্যাক ওভারফ্লো প্রশ্নটি প্রথমে যথেষ্ট বলে মনে হলেও, আমি আপনার মন্তব্যগুলি থেকে বুঝতে পেরেছি কেন আপনার এখনও এই বিষয়ে সন্দেহ থাকতে পারে। আমার কাছে, দুটি UNIX সাবসিস্টেমগুলি (প্রক্রিয়া এবং ফাইল) যোগাযোগ করার সময় ঠিক এই ধরনের জটিল পরিস্থিতি জড়িত।

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

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

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

গিলসের উত্তরের এক্সিকিউটেবল অংশের প্রতিস্থাপনের দিকে যদি আপনার নজর থাকে তবে আপনি দেখতে পাবেন যে আপনি ফাইলটি কীভাবে সম্পাদনা / মুছবেন তার উপর নির্ভর করে কার্নেল সর্বদা ফাইল সাবসিস্টেমের মধ্যে প্রয়োগকৃত একটি ব্যবস্থার মাধ্যমে আলাদাভাবে প্রতিক্রিয়া / মানিয়ে নেবে।

  • আপনি যদি কৌশলটির একটিকে চেষ্টা করেন ( শূন্য / লেখার জন্য মুক্ত / কাটা বা নতুন আকারে ওপেন / রাইটিং / ট্রুনসেট ), আপনি দেখতে পাবেন যে কার্নেল আপনার অনুরোধটি পরিচালনা করতে বিরক্ত করবে না। আপনি একটি ত্রুটি পাবেন 26: পাঠ্য ফাইল ব্যস্ত ( ETXTBSY)। যাই হোক না কেন কোনও ফল।
  • আপনি যদি কৌশল দুটি চেষ্টা করে থাকেন তবে প্রথম পদক্ষেপটি হ'ল আপনার এক্সিকিউটেবলকে মোছা। তবে, যেহেতু এটি কোনও প্রক্রিয়া দ্বারা ব্যবহৃত হচ্ছে, তাই ফাইল সাবসিস্টেমটি ফাইলটিকে (এবং এর ইনোড) ডিস্ক থেকে সত্যই মুছে ফেলা থেকে বিরত রাখবে । এই জায়গা থেকে, পুরানো ফাইলের সামগ্রীতে অ্যাক্সেসের একমাত্র উপায় হ'ল এটির ইনোডের মাধ্যমে এটি করা, যা প্রক্রিয়া সাবসিস্টেমটি যখনই পাঠ্য বিভাগে নতুন ডেটা লোড করার প্রয়োজন হয় (অভ্যন্তরীণভাবে, পথগুলি ব্যবহার করার কোনও মানে হয় না) এগুলি ইনোডে অনুবাদ করার সময়)। আপনি লিঙ্কযুক্ত থাকলেওফাইলটি (এর সমস্ত পথ সরিয়ে দেওয়া হয়েছে), প্রক্রিয়াটি এখনও এটিকে এমনভাবে ব্যবহার করতে পারে যেন আপনি কিছুই করেন নি। পুরানো পথ দিয়ে একটি নতুন ফাইল তৈরি করা কোনও পরিবর্তন করে না: নতুন ফাইলটিকে সম্পূর্ণ নতুন ইনোড দেওয়া হবে, যার চলমান প্রক্রিয়াটির কোনও জ্ঞান নেই।

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

  • কৌশল তিনটি বেশ সমান কারণ mvঅপারেশনটি একটি পারমাণবিক। এটির জন্য সম্ভবত renameসিস্টেম কল ব্যবহারের প্রয়োজন হবে এবং কার্নেল মোডে থাকাকালীন প্রক্রিয়াগুলিতে বাধা দেওয়া যাবে না, যতক্ষণ না এটি সম্পন্ন হয় (সফলভাবে না হয়) যতক্ষণ না এই অপারেশনটিতে কিছুই হস্তক্ষেপ করতে পারে না। আবার, পুরানো ফাইলের ইনোডের কোনও পরিবর্তন নেই: একটি নতুন তৈরি করা হয়েছে, এবং ইতিমধ্যে চলমান প্রক্রিয়াগুলির কোনও জ্ঞান থাকবে না, এমনকি এটি পুরানো ইনোডের লিঙ্কগুলির মধ্যে একটির সাথে যুক্ত থাকলেও।

কৌশল 3 এর সাথে নতুন ফাইলটিকে বিদ্যমান নামে স্থানান্তরিত করার পদক্ষেপটি পুরাতন সামগ্রীর দিকে পরিচালিত ডিরেক্টরি এন্ট্রি সরিয়ে দেয় এবং নতুন সামগ্রীর দিকে পরিচালিত ডিরেক্টরি এন্ট্রি তৈরি করে। এটি একটি পারমাণবিক অপারেশনে করা হয়, সুতরাং এই কৌশলটির একটি বড় সুবিধা রয়েছে: কোনও প্রক্রিয়া যে কোনও সময় ফাইলটি খুললে এটি পুরানো সামগ্রী বা নতুন সামগ্রী দেখতে পাবে - মিশ্র সামগ্রী বা ফাইলটি না পাওয়ার কোনও ঝুঁকি নেই বিদ্যমান।

একটি ফাইল পুনরায় সংকলন : ব্যবহার করার সময় gcc(এবং আচরণটি সম্ভবত অন্যান্য অনেক সংকলকগুলির জন্য একই রকম), আপনি কৌশল 2 ব্যবহার করছেন You আপনি দেখতে পাচ্ছেন যে straceআপনার সংকলকটির একটি প্রক্রিয়া চালিয়ে :

stat("a.out", {st_mode=S_IFREG|0750, st_size=8511, ...}) = 0
unlink("a.out") = 0
open("a.out", O_RDWR|O_CREAT|O_TRUNC, 0666) = 3
chmod("a.out", 0750) = 0
  • কম্পাইলার সনাক্ত করে যে ফাইল আগে থেকেই মাধ্যমে বিদ্যমান statএবং lstatসিস্টেম কল।
  • ফাইলটি লিঙ্কযুক্ত । এখানে, যদিও এটি নামের মাধ্যমে আর অ্যাক্সেসযোগ্য নয় a.out, এর ইনোড এবং বিষয়বস্তু ডিস্কে থেকে যায়, যতক্ষণ না তারা ইতিমধ্যে চলমান প্রক্রিয়াগুলি দ্বারা ব্যবহৃত হয়।
  • একটি নতুন ফাইল তৈরি করা হয় এবং নামের অধীনে কার্যকর করা যায় a.out। এটি একেবারে নতুন ইনোড এবং ব্র্যান্ডের নতুন বিষয়বস্তু, যা ইতিমধ্যে চলমান প্রক্রিয়াগুলি যত্ন করে না।

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


চমত্কার, বিস্তারিত উত্তর। এটি আমার বিভ্রান্তির ব্যাখ্যা দেয়। সুতরাং আমি কী ধরে নিচ্ছি যে ইনোডটি এখনও উপলব্ধ তাই মূল বাইনারি ফাইল থেকে প্রাপ্ত ডেটাটি এখনও ডিস্কে রয়েছে এবং তাই ডিস্কে dfফ্রি বাইট সংখ্যা বের করার জন্য ব্যবহার করা ভুল কারণ এটি ইনোড নেয় না সমস্ত ফাইল সিস্টেমের লিঙ্কগুলি অ্যাকাউন্টে নেওয়া হয়েছে? তাহলে আমার ব্যবহার করা উচিত df -i? (এটি কেবল একটি প্রযুক্তিগত কৌতূহল, সঠিক ডিস্কের ব্যবহার সম্পর্কে আমার সত্যিই জানা দরকার নেই!)
টেক্সাসফ্লুড

1
কেবল ভবিষ্যতের পাঠকদের জন্য স্পষ্ট করে বলার জন্য - আমার বিভ্রান্তিটি ছিল যে আমি মৃত্যুদন্ড কার্যকর করার বিষয়ে ভেবেছিলাম, পুরো বাইনারিটি র‌্যামে লোড করা হবে, সুতরাং যদি র‌্যাম ছোট হয়, তবে বাইনারিটির কিছু অংশ র‌্যাম ছেড়ে চলে যেতে হবে এবং ডিস্ক থেকে পুনরায় লোড করতে হবে - যা আপনি যদি ফাইলটি পরিবর্তন করেন তবে সমস্যা সৃষ্টি করুন। তবে উত্তরটি পরিষ্কার করে দিয়েছে যে বাইনারিটি সত্যই কখনই ডিস্ক থেকে সরানো হয় না যদিও আপনি rmবা mvএটি মূল ফাইলের ইনোড হিসাবে সমস্ত প্রক্রিয়াগুলি সেই ইনোডের সাথে তাদের লিঙ্কটি সরিয়ে না দেওয়া পর্যন্ত সরানো হয় না।
টেক্সাসফ্লুড

@ টেক্সাসফ্লুড অবিকল একবার সমস্ত পাথ সরিয়ে ফেলা হয়ে গেলে কোনও নতুন প্রক্রিয়া ( dfঅন্তর্ভুক্ত) ইনোড সম্পর্কিত তথ্য পেতে পারে না। আপনি যে নতুন তথ্য খুঁজে পান তা নতুন ফাইল এবং নতুন ইনোডের সাথে সম্পর্কিত। এখানে মূল বক্তব্যটি হ'ল প্রক্রিয়া সাবসিস্টেমটি এই সমস্যায় আগ্রহী না, সুতরাং মেমরি পরিচালনার ধারণা (চাহিদা পেজিং, প্রক্রিয়া অদলবদল, পৃষ্ঠা ত্রুটি, ...) সম্পূর্ণ অপ্রাসঙ্গিক। এটি একটি ফাইল সাবসিস্টেম সমস্যা এবং এটি ফাইল সাবসিস্টেম দ্বারা যত্ন নেওয়া হয়। প্রক্রিয়া সাবসিস্টেম এটি নিয়ে বিরক্ত করে না, এটি এখানে এটি নয়।
জন ডাব্লু এইচ স্মিথ 12

@ টেক্সাসফ্লুড সম্পর্কিত একটি নোট df -i: এই সরঞ্জামটি সম্ভবত fs 'সুপারব্লক, বা এর ক্যাশে থেকে তথ্য পুনরুদ্ধার করে যার অর্থ এটি পুরাতন বাইনারি (যার জন্য সমস্ত লিঙ্ক মুছে ফেলা হয়েছে) এর ইনোড অন্তর্ভুক্ত করতে পারে। যদিও এর অর্থ এই নয় যে নতুন প্রক্রিয়াগুলি সেই পুরানো ডেটাটি ব্যবহার করতে মুক্ত।
জন ডব্লিউ এইচ স্মিথ

2

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

এটি অবশ্যই নিশ্চিত করতে হবে।


2

.Jar ফাইলটি প্রতিস্থাপন করার সময় এটি সর্বদা হয় না। জার রিসোর্স এবং কিছু রানটাইম রিফ্লেকশন ক্লাস লোডার প্রোগ্রামটি স্পষ্টভাবে তথ্যের জন্য অনুরোধ না করা পর্যন্ত ডিস্ক থেকে পড়া হয় না।

এটি কেবলমাত্র একটি ইস্যু কারণ একটি জার কেবল একটি সম্পাদনযোগ্য মেমরির মধ্যে ম্যাপ হয়ে যাওয়া পরিবর্তে একটি সংরক্ষণাগার। এটি সামান্য অফ স্টপিক তবে এটি এখনও আপনার প্রশ্নের একটি অফশুট এবং এমন কিছু যা আমি নিজেই পায়ে গুলি করেছি।

এক্সিকিউটেবলের জন্য: হ্যাঁ। জার ফাইলগুলির জন্য: সম্ভবত (বাস্তবায়নের উপর নির্ভর করে)।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.