সি # একটি স্ট্যাক ওভারফ্লো ব্যতিক্রম ধরা


115

আমার কাছে এমন পদ্ধতিতে পুনরাবৃত্ত কল রয়েছে যা স্ট্যাকের ওভারফ্লো ব্যতিক্রম ছুঁড়ে দেয়। প্রথম কলটি একটি ক্রিচ ব্লক দ্বারা ঘিরে রয়েছে তবে ব্যতিক্রম ধরা পড়েনি।

স্ট্যাক ওভারফ্লো ব্যতিক্রমগুলি কি বিশেষ উপায়ে আচরণ করে? আমি কি ব্যতিক্রমটি সঠিকভাবে ধরতে / পরিচালনা করতে পারি?

প্রাসঙ্গিক কিনা তা নিশ্চিত নয়, তবে অতিরিক্ত তথ্য:

  • ব্যতিক্রমটি মূল থ্রেডে ছোঁড়া হয় না

  • কোডটি যেখানে ব্যতিক্রম নিক্ষেপ করছে সেটিকে ম্যানুয়ালি এসেম্বলি লোড করা হয়। লোডফ্রোম (...)।


3
@ রিচার্ডড, অবশ্যই আমি বাগটি ঠিক করেছি কারণ এটি একটি বাগ ছিল। তবে সমস্যাটি অন্যরকমভাবে উপস্থিত হতে পারে এবং আমি এটি পরিচালনা করতে চাই
টোটো

7
সম্মত, একটি স্ট্যাক ওভারফ্লো একটি গুরুতর ত্রুটি যা ধরা যায় না কারণ এটি ধরা উচিত নয় । পরিবর্তে ভাঙা কোডটি ঠিক করুন।
ইয়ান কেম্প

11
@ রিচার্ডড: যদি কেউ উদাহরণস্বরূপ একটি পুনরাবৃত্ত-বংশদ্ভুত পার্সার ডিজাইন করতে চায় এবং হোস্ট মেশিনের দ্বারা প্রয়োজনীয় প্রয়োজনীয়তার চেয়ে গভীরতার জন্য কৃত্রিম সীমা চাপায় না, তবে কীভাবে এটি করা উচিত? যদি আমার ড্রাথার থাকে তবে স্ট্যাকক্রিটিকাল ব্যতিক্রম থাকত যা স্পষ্টভাবে ধরা যেতে পারে, যা সামান্য স্ট্যাকের জায়গা বাকি থাকতেই বরখাস্ত করা হবে; এটি প্রকৃতপক্ষে নিক্ষেপ না করা পর্যন্ত এটি নিজেকে অক্ষম করে দেবে এবং নিরাপদ পরিমাণ স্ট্যাকের স্থান অবধি অবধি ধরা পড়বে না।
সুপারক্যাট

2
এই প্রশ্নটি দরকারী - যদি স্ট্যাকের ওভারফ্লো ব্যতিক্রম ঘটে তবে আমি ইউনিট টেস্টে ব্যর্থ হতে চাই - তবে নুনিট কেবলমাত্র অন্যান্য ব্যতিক্রমগুলির মতো এটির ব্যর্থতার পরিবর্তে পরীক্ষাকে "উপেক্ষা" বিভাগে নিয়ে যায় - আমাকে এটি ধরতে হবে এবং Assert.Failপরিবর্তে একটি করতে। এত গুরুত্ব সহকারে - আমরা কীভাবে এটি সম্পর্কে যেতে পারি?
BrainSlugs83

উত্তর:


109

স্ট্যাকওভারফ্লো ব্যতিক্রমটি 2.0 দিয়ে শুরু করা কেবলমাত্র নিম্নলিখিত পরিস্থিতিতে ধরা যেতে পারে।

  1. সিএলআরটি একটি হোস্ট করা পরিবেশে চলছে * যেখানে হোস্টটি বিশেষত স্ট্যাকওভারফ্লো ব্যতিক্রমগুলি পরিচালনা করার অনুমতি দেয়
  2. স্ট্যাকওভারফ্লো ব্যতিক্রমটি ব্যবহারকারী কোড দ্বারা নিক্ষেপ করা হয়েছে এবং প্রকৃত স্ট্যাক ওভারফ্লো পরিস্থিতির কারণে নয় ( রেফারেন্স )

* "হোস্টেড এনভায়রনমেন্ট" যেমন "আমার কোড সিএলআর হোস্ট করে এবং আমি সিএলআর এর বিকল্পগুলি কনফিগার করি" এবং "আমার কোড শেয়ার্ড হোস্টিংয়ে চলে না"


27
যদি এটি কোনও প্রাসঙ্গিক দৃশ্যের মধ্যে ধরা না যায় তবে স্ট্যাকওভারফ্লোএক্সেপশন অবজেক্টটি কেন বিদ্যমান?
মানু

9
@ মানু কমপক্ষে কয়েকটি কারণে। 1) এটি কি ধরা পড়েছিল, 1.1 তে, এরকম এবং এর একটি উদ্দেশ্য ছিল। 2) আপনি সিএলআর হোস্ট করছেন তবে এটি এখনও ধরা যেতে পারে তাই এটি এখনও একটি বৈধ ব্যতিক্রম প্রকার
JaredPar

3
যদি এটি ধরা না যায় ... কেন উইন্ডোজ ইভেন্টটি ব্যাখ্যা করে যে ঘটেছে তা ডিফল্টরূপে পুরো স্ট্যাক ট্রেসকে অন্তর্ভুক্ত করে না?

10
কোনও হোস্ট করা পরিবেশে স্ট্যাকওভারফ্লো এক্সপસેজগুলি হ্যান্ডেল করার অনুমতি দেওয়ার বিষয়ে কীভাবে যায়? আমি জিজ্ঞাসার কারণটি হ'ল কারণ আমি একটি পরিবেশিত পরিবেশ চালাচ্ছি এবং আমার এই সঠিক সমস্যাটি রয়েছে, যেখানে এটি পুরো অ্যাপ্লিকেশন পুলটি ধ্বংস করে। আমি বরং এটি থ্রেডটি বাতিল করতে চাই, যেখানে এটি শীর্ষে ফিরে যেতে পারে এবং আমি ত্রুটিটি লগইন করতে পারি এবং অ্যাপপুলের সমস্ত থ্রেড হত্যা না করেই চালিয়ে যেতে পারি।
Brain2000

Starting with 2.0 ..., আমি কৌতূহলগুলি, কীভাবে তাদের এসও ধরতে বাধা দিচ্ছে এবং কীভাবে এটি সম্ভব হয়েছিল 1.1(আপনি এটি আপনার মন্তব্যে উল্লেখ করেছেন)?
এমকাজেম আখগ্রি

47

সঠিক উপায় হ'ল ওভারফ্লো ঠিক করা, কিন্তু ....

আপনি নিজেকে একটি বড় স্ট্যাক দিতে পারেন: -

using System.Threading;
Thread T = new Thread(threadDelegate, stackSizeInBytes);
T.Start();

আপনি সিস্টেম.ডায়াগনস্টিক্স.স্ট্যাকট্রেস ফ্রেমকাউন্ট সম্পত্তি ব্যবহার করতে পারেন আপনার ব্যবহৃত ফ্রেমগুলি গণনা করতে এবং যখন কোনও ফ্রেমের সীমা পৌঁছে যায় তখন নিজের ব্যতিক্রম ছুঁড়ে ফেলতে পারেন।

বা, আপনি স্ট্যাকের বাকী অংশের আকার গণনা করতে পারেন এবং এটি যখন কোনও প্রান্তিকের নীচে পড়ে যান তখন নিজের ব্যতিক্রম ছুঁড়ে ফেলতে পারেন: -

class Program
{
    static int n;
    static int topOfStack;
    const int stackSize = 1000000; // Default?

    // The func is 76 bytes, but we need space to unwind the exception.
    const int spaceRequired = 18*1024; 

    unsafe static void Main(string[] args)
    {
        int var;
        topOfStack = (int)&var;

        n=0;
        recurse();
    }

    unsafe static void recurse()
    {
        int remaining;
        remaining = stackSize - (topOfStack - (int)&remaining);
        if (remaining < spaceRequired)
            throw new Exception("Cheese");
        n++;
        recurse();
    }
}

শুধু পনির ধর। ;)


47
Cheeseনির্দিষ্ট থেকে দূরে। আমি যেতে চাইthrow new CheeseException("Gouda");
সি। এভেনহুইস

13
@ সি। এভেনহুইস এতে কোনও সন্দেহ নেই যে গৌদা একটি ব্যতিক্রমী পনির এটি রোলিংচিজএক্সেপশন হওয়া উচিত ("ডাবল গ্লোস্টার") সত্যই পনির

3
লওল, ১) ফিক্সিং সম্ভব নয় কারণ এটি ধরা ছাড়া আপনি প্রায়শই জানেন না কোথায় এটি ঘটে 2) স্ট্যাকসাইজ বৃদ্ধি অবিরাম পুনরাবৃত্তি এবং মজাদার সাথে 3) সঠিক জায়গায় স্ট্যাক চেক করা
প্রথমটির

2
কিন্তু আমি ল্যাকটোজ অসহিষ্ণু আছি
redoc

39

স্ট্যাকওভারফ্লো এক্সপেশন এর এমএসডিএন পৃষ্ঠা থেকে :

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

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


23

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

এটি করতে, আপনাকে 'ডিবাগ' মেনু থেকে ব্যতিক্রম সেটিংসটি খুলতে হবে। ভিজ্যুয়াল স্টুডিওর পুরানো সংস্করণগুলিতে এটি 'ডিবাগ' - 'ব্যতিক্রম'; নতুন সংস্করণগুলিতে এটি 'ডিবাগ' - 'উইন্ডোজ' - 'ব্যতিক্রমী সেটিংস' এ রয়েছে।

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


1
ডিবাগ কোথায় - ভিএস 2015 ব্যতিক্রম?
ফ্রেনকিবি

1
ডিবাগ - উইন্ডোজ - ব্যতিক্রম সেটিংস
সাইমন

15

উপরে বেশ কয়েকবার উল্লিখিত হিসাবে, কোনও স্ট্যাকওভারফ্লো এক্সেক্সশন ধরা সম্ভব নয় যা সিস্টেম দ্বারা দূষিত প্রক্রিয়া-অবস্থার কারণে উত্থাপিত হয়েছিল। তবে একটি ইভেন্ট হিসাবে ব্যতিক্রমটি লক্ষ্য করার একটি উপায় রয়েছে:

http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx

.NET ফ্রেমওয়ার্ক সংস্করণ 4 দিয়ে শুরু করে, ইভেন্টটি হ্যান্ডলারটি সুরক্ষা-সমালোচনামূলক না হয়ে থাকে এবং হ্যান্ডলপ্রসেসকর্প্রেস্টস্টেট এক্সেক্সেশনঅ্যাট্রিবিউট অ্যাট্রিবিউট না থাকলে প্রক্রিয়াটির অবস্থা যেমন স্ট্যাক ওভারফ্লো বা অ্যাক্সেস লঙ্ঘনকে দূষিত করে, এই ইভেন্টটি উত্থাপিত হয় না that

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

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


6

হ্যাঁ সিএলআর 2.0 থেকে স্ট্যাক ওভারফ্লো একটি পুনরুদ্ধারযোগ্য পরিস্থিতি হিসাবে বিবেচিত হয়। সুতরাং রানটাইম এখনও প্রক্রিয়াটি বন্ধ করে দেয়।

বিস্তারিত সন্তুষ্ট জন্য ডকুমেন্টেশন দেখুন http://msdn.microsoft.com/en-us/library/system.stackoverflowexception.aspx


সিএলআর 2.0 থেকে একটি StackOverflowExceptionডিফল্টরূপে প্রক্রিয়াটি সমাপ্ত করে।
ব্রায়ান রাসমুসেন

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

5

আপনি পারবেন না। সিএলআর আপনাকে অনুমতি দেবে না। একটি স্ট্যাক ওভারফ্লো একটি মারাত্মক ত্রুটি এবং এর থেকে পুনরুদ্ধার করা যায় না।


সুতরাং আপনি কীভাবে একটি ইউনিট টেস্টকে এই ব্যতিক্রমের জন্য ব্যর্থ করতে পারেন যদি ক্যাচযোগ্য হওয়ার পরিবর্তে ইউনিট পরীক্ষা রানারকে ক্র্যাশ করে?
BrainSlugs83

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

5

আপনি বেশিরভাগ পোস্টের ব্যাখ্যা দিচ্ছেন না, আমাকে অন্য একটি অঞ্চল যুক্ত করুন:

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


3

এটি অসম্ভব, এবং একটি ভাল কারণে (একের জন্য, এই সমস্ত ক্যাপটি (ব্যতিক্রম) {{কাছাকাছি সম্পর্কে চিন্তা করুন)।

যদি আপনি স্ট্যাক ওভারফ্লোয়ের পরে মৃত্যুদন্ড কার্যকর করতে চান, তবে কোনও অন্য অ্যাপডোমাইনে বিপজ্জনক কোড চালান। সিএলআর নীতিগুলি মূল ডোমেনকে প্রভাবিত না করে ওভারফ্লোতে বর্তমান অ্যাপডোমেনকে শেষ করতে সেট করা যেতে পারে।


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

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