সংকলকটি ক্র্যাশ করা অনির্ধারিত আচরণযুক্ত সোর্স কোডের পক্ষে কি আইনী?


85

আসুন আমি বলি যে আমি কিছু বাজে লেখা সি ++ উত্স কোড সংকলন করতে যাচ্ছি যা অপরিজ্ঞাত আচরণের জন্য প্রার্থনা করে এবং তাই (তারা যেমন বলে) "কিছু ঘটতে পারে"।

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


22
"ইউবি হ'ল ইউবি it সাথে থাকুন" ... অপেক্ষা করবেন না। "দয়া করে একটি এমসিভিই পোস্ট করুন।" ... অপেক্ষা নেই। আমি প্রশ্নটি পছন্দ করি না এমন সমস্ত প্রতিক্রিয়াগুলির জন্য যা এটি অবৈধভাবে ট্রিগার করে। :-)
ইউনোশচ

14
আসলেই কোনও সীমাবদ্ধতা নেই, যার কারণেই বলা হয়েছে যে ইউবি অনুনাসিক দানবদের ডেকে আনতে পারে ।
কিছু প্রোগ্রামার ডুড

15
ইউবি লেখককে এসওতে একটি প্রশ্ন পোস্ট করতে পারে । : পি
তানভীর বদর

46
সি ++ স্ট্যান্ডার্ড যা বলুক না কেন, আমি যদি সংকলক লেখক হয়ে থাকি তবে আমি অবশ্যই এটি আমার সংকলকটিতে বাগ হিসাবে বিবেচনা করব। সুতরাং আপনি যদি এটি দেখতে পাচ্ছেন তবে একটি ত্রুটি প্রতিবেদন করুন।
জন

9
@ লিফওয়িলার্টস এটি ৮০ এর দশকে ফিরে এসেছিল। সঠিক নির্মাণটি আমার মনে নেই, তবে মনে হয় এটি একটি কনভোলিউটেড ভেরিয়েবল টাইপ ব্যবহারের উপর জড়িত। আমি প্রতিস্থাপনের পরে আমার একটি "আমি কী ভাবছিলাম - জিনিসগুলি সেভাবে কাজ করে না" মুহুর্তে। আমি কেবল মেশিনটি রিবুট করার জন্য, নির্মাণটি প্রত্যাখ্যান করার জন্য কম্পাইলারকে দোষ দিইনি। আমি সন্দেহ করি যে কেউ আজ সেই সংকলকের মুখোমুখি হবে। এটি এইচপি 64000 এর জন্য 68000 মাইক্রোপ্রসেসরকে লক্ষ্য করে এইচপি সি ক্রস সংকলক ছিল।
আভি বার্গার

উত্তর:


71

অপরিবর্তিত আচরণের আদর্শিক সংজ্ঞাটি নিম্নরূপ:

[সংজ্ঞায়িত]

এই আন্তর্জাতিক স্ট্যান্ডার্ড কোনও প্রয়োজনের জন্য চাপায় না এমন আচরণ

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

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


43
যে বলেন, যদি আপনি করতে পারেন আসলে একটি কম্পাইলার কোনো স্যান্ডবক্সিং ছাড়াই কম্পাইল-সময়ে নির্বিচারে কোড চালানো, তারপর বিভিন্ন নিরাপত্তা মানুষ হবে পেতে খুব এটি সম্পর্কে জানতে আগ্রহী। একইটি সংকলকটি সেগফল্টিংয়ের জন্য যায়।
কেভিন

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

8
টিসস্ট্রগা আমি বাজি ধরেছি যে চথুলহু একটি দুর্দান্ত এফ 1 ড্রাইভার তৈরি করবে make
জেটা-ব্যান্ড

35
"যদি কোনও বাস্তবায়ন আপনার পাসওয়ার্ডগুলি চুরি করে তবে এটি স্ট্যান্ডার্ডে বর্ণিত কোনও চুক্তির লঙ্ঘন নয়" " কোডটি ইউবি রয়েছে কিনা তা নির্বিশেষে এটি সত্য, তাই না? সংমিত প্রোগ্রামটি যা করা উচিত তা কেবল স্ট্যান্ডার্ডটি নির্দেশ করে - একটি সংকলক যা কোডটি সঠিকভাবে সংকলন করে তবে প্রক্রিয়াতে আপনার পাসওয়ার্ডগুলি চুরি করে মানটিকে অমান্য করবে না।
Carmeister

8
@ কারমিস্টার, ওহ, এটি একটি ভাল বিষয়, আমি যখনই "ইউবি পারমাণবিক যুদ্ধ শুরু করার জন্য সংকলককে অনুমতি প্রদান করি" যুক্তিগুলি পপ আপ করে দেয় আমি অবশ্যই তাদের মনে করিয়ে দেওয়ার বিষয়টি নিশ্চিত করব। আবার।
ইলকচাচু

8

NUL-deref বা শূন্য দ্বারা বিভাজনের মতো আমরা সাধারণত উদ্বিগ্ন বেশিরভাগ ধরণের ইউবি রানটাইম ইউবি। একটি ফাংশন সংকলন যা মৃত্যুদন্ড কার্যকর করা হলে রানটাইম ইউবির কারণ হতে পারে সংকলকটি ক্র্যাশ হওয়ার কারণ নয়। যদি না এটি প্রমাণ করতে পারে যে ফাংশনটি (এবং ফাংশনটির মধ্য দিয়ে সেই পথটি) অবশ্যই প্রোগ্রাম দ্বারা সম্পাদিত হবে

(২ য় মতামত: সম্ভবত আমি সংকলনের সময় টেমপ্লেট / কনস্টেক্সপ্রের প্রয়োজনীয় মূল্যায়ন বিবেচনা করিনি that সম্ভবত এটির সময় ইউবি অনুবাদকের সময় স্বেচ্ছাসূচক অদ্ভুততার কারণ হতে পারে এমনকি ফলাফলের ক্রিয়াকলাপটি কখনই ডাকা হয় না))

অনুবাদ সময় ব্যবহারকে আইএসও সি ++ উদ্ধৃতি অংশ মধ্যে @ গল্পবলিয়ে এর উত্তর আইএসও সি মান ব্যবহৃত ভাষা একই। সি constexprসংকলনের সময় টেমপ্লেট বা বাধ্যতামূলক eval অন্তর্ভুক্ত নয় ।

তবে মজাদার ঘটনা : আইএসও সি একটি নোটে বলেছেন যে অনুবাদটি যদি সমাপ্ত হয় তবে এটি অবশ্যই একটি ডায়াগোনস্টিক বার্তা সহ থাকতে হবে। বা "অনুবাদ করার সময় আচরণ করা ... একটি দলিলযুক্ত পদ্ধতিতে"। আমি মনে করি না "পরিস্থিতি সম্পূর্ণ উপেক্ষা করা" অনুবাদ থামানো সহ পড়া যায় read


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


সেখানে যে UB কোন ধরনের জিনিস ঘটবে কম্পাইল সময়ে। এটা হতে পারে প্রোফাইল সঞ্চালনের একটি নির্দিষ্ট পথ বরাবর কম্পাইলার, কিন্তু সি ++ পদ এটা করেননি ঘটেছে সঞ্চালনের পৌছানোর পর্যন্ত যে একটা ফাংশন মাধ্যমে মৃত্যুদন্ড পথ।

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

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

int cause_UB() {
    int x=0;
    return 1 / x;      // UB if ever reached.
 // Note I'm avoiding  x/0  in case that counts as translation time UB.
 // UB still obvious when optimizing across statements, though.
}

int main(){
    if (0)
        cause_UB();
}

এর জন্য ব্যবহারের ক্ষেত্রে সি প্রিপ্রসেসর, বা constexprভেরিয়েবলগুলি এবং সেই ভেরিয়েবলগুলিতে শাখা জড়িত থাকতে পারে যা কিছু পথে বাজে কথা বাড়ে যা ধ্রুবকগুলির পছন্দগুলির জন্য কখনও পৌঁছায় না।

সংকলন-সময়-দৃশ্যমান ইউবির জন্য মৃত্যুদন্ড কার্যকর করার পথগুলি কখনই গ্রহণ করা হবে বলে ধরে নেওয়া যায় না, উদাহরণস্বরূপ x86 এর সংকলক ud2এর সংজ্ঞা হিসাবে একটি (অবৈধ নির্দেশের ব্যতিক্রম) নির্গত করতে পারে cause_UB()। বা কোনও ফাংশনের মধ্যে, যদি কোনও এক প্রান্তে প্রমাণযোগ্য ইউবি if()বাড়ে , শাখাটি সরানো যেতে পারে।

কিন্তু সংকলকটি এখনও বুদ্ধিমান এবং সঠিক উপায়ে অন্য সমস্ত কিছু সংকলন করতে হয়েছে। সমস্ত পাথ যেগুলির মুখোমুখি হয় না (বা মুখোমুখি হওয়ার পক্ষে প্রমাণিত হতে পারে না) ইউবি এখনও অবশ্যই এমন একটি সংশ্লেষ করতে হবে যা সি ++ অ্যাবস্ট্রাক্ট মেশিনটি চালাচ্ছিল এমন হিসাবে কার্যকর করে।


আপনি তর্ক করতে পারেন যে শর্তহীন সংকলন-সময়-দৃশ্যমান ইউবি mainএই নিয়মের ব্যতিক্রম। অথবা অন্যথায় সংকলন-সময়-প্রমাণযোগ্য যে কার্যকরভাবে শুরু হওয়া কার্যকর mainগ্যারান্টিযুক্ত ইউবিতে পৌঁছায়।

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


শাখাগুলির ভিতরে সম্ভাব্য বা প্রযোজ্য ইউবিযুক্ত ফাংশন

মৃত্যুদণ্ডের কোনও প্রদত্ত পথ বরাবর ইউবি পূর্ববর্তী সমস্ত কোড "দূষিত" করতে পিছনের দিকে পৌঁছে যায়। তবে অনুশীলনে সংকলকরা কেবল তখনই সেই নিয়মের সুযোগ নিতে পারে যখন তারা প্রকৃতপক্ষে প্রমাণ করতে পারে যে মৃত্যুদণ্ডের পথগুলি সময়-দৃশ্যমান ইউবি সংকলন করে। যেমন

int minefield(int x) {
    if (x == 3) {
        *(char*)nullptr = x/0;
    }

    return x * 5;
}

সংকলকটি এমন asm তৈরি করতে হবে যা INT_MIN এবং INT_MAX এ স্বাক্ষরিত ওভারফ্লো ইউবির কারণ হিসাবে xএমন পয়েন্টগুলি পর্যন্ত 3 ব্যতীত অন্য সকলের জন্য কাজ করে x * 5। যদি এই ফাংশনটি কখনও কল করা না হয় x==3তবে অবশ্যই প্রোগ্রামটিতে কোনও ইউবি নেই এবং অবশ্যই লিখিত হিসাবে কাজ করতে হবে।

আমরা সম্ভবত if(x == 3) __builtin_unreachable();জিএনইউ সি-তে লিখেছিলাম এমন সংকলকটি বলতে xযা অবশ্যই 3 নয়।

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


3

"আইনী" এর অর্থ এখানে কী? এই মানগুলি অনুসারে যে কোনও কিছুই সি স্ট্যান্ডার্ড বা সি ++ স্ট্যান্ডার্ডের বিরোধিতা করে না তা আইনী। যদি আপনি কোনও বিবৃতি কার্যকর করেন i = i++;এবং ফলস্বরূপ ডাইনোসররা বিশ্বকে দখল করে নেয়, তবে এটি মানদণ্ডের বিরোধী নয়। এটি পদার্থবিজ্ঞানের আইনগুলির বিরোধিতা করে না, সুতরাং এটি ঘটতে যাচ্ছে না :-)

যদি সংজ্ঞায়িত আচরণটি আপনার সংকলককে ক্র্যাশ করে তবে তা সি বা সি ++ মান লঙ্ঘন করে না। তবে এর অর্থ এই নয় যে সংকলকের গুণমানটি (এবং সম্ভবত হওয়া উচিত) উন্নত হতে পারে।

সি স্ট্যান্ডার্ডের পূর্ববর্তী সংস্করণগুলিতে এমন বিবৃতি ছিল যা ত্রুটিগুলি ছিল বা অপরিজ্ঞাত আচরণের উপর নির্ভর করে না:

char* p = 1 / 0;

একটি চরকে * একটি ধ্রুবক 0 নির্ধারিত অনুমোদিত is অ-শূন্য ধ্রুবককে অনুমতি দেওয়া হয় না। যেহেতু 1/0 এর মান নির্ধারিত আচরণ, তাই সংজ্ঞাকারীর এই বিবৃতিটি গ্রহণ করা উচিত এবং না করা উচিত তা অপরিজ্ঞাত আচরণ। (আজকাল, 1/0 "পূর্ণসংখ্যার ধ্রুবক অভিব্যক্তি" এর সংজ্ঞা আর মেলে না)।


4
সুনির্দিষ্টভাবে বলতে গেলে: বিশ্বজুড়ে ডাইনোসররা পদার্থবিজ্ঞানের কোনও আইনের (যেমন জুরাসিক পার্কের বৈচিত্র) বিরোধী নয়। এটি মাত্র অত্যন্ত অসম্ভব। :)
freakish

-1

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

সুতরাং, কোনও সি প্রোগ্রাম অনুবাদ করার চেষ্টা করার ফলস্বরূপ কী ঘটতে পারে তার সাধারণভাবে সীমাবদ্ধতা নেই, এমনকি যদি কেউ এটি চালানোর জন্য কোনও প্রচেষ্টা না করে।


যে কোনও প্রোগ্রামিং ভাষার কোনও অনুবাদক বা সংকলক সম্পর্কে একই কথা বলা যেতে পারে। বা, এই বিষয়টির জন্য, যে কোনও প্রোগ্রাম।
রবার্ট হার্ভে

@ রবার্টহারভে: অনেক প্রোগ্রামিং ভাষার স্পেসিফিকেশন এই জাতীয় জিনিসগুলির বিষয়ে অনেক বেশি নির্দিষ্ট। যদি কোনও ভাষার বৈশিষ্ট্য বলে যে কোনও নির্দিষ্ট নির্দেশিকা একটি স্ট্রিমের ইনপুট পড়বে যার ওএস পাথ নির্দিষ্ট করা হয়েছে, এবং ওএস কোনও নির্দিষ্ট পাথ পড়ার সময় অদ্ভুত কিছু করে, যা ভাষা বর্ণের নিয়ন্ত্রণের বাইরে থাকবে, তবে আমি তা করি না মনে হয় বেশিরভাগ ভাষার চশমাগুলি তাদের অবসর সময়ে স্বেচ্ছাসেবী ফ্যাশনে যেমন নির্দেশনা প্রক্রিয়াকরণের জন্য প্রয়োগগুলি কার্ট ব্লাঞ্চকে দেবে, এমনকি এটি কোনও ডকুমেন্ট না করে এমনকী প্ল্যাটফর্মগুলিতে যা অন্যথায় আচরণকে সংজ্ঞায়িত করে।
সুপারক্যাট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.