অ্যাক্সেস লঙ্ঘন ব্যতিক্রম ধরা?


89

উদাহরণ

int *ptr;
*ptr = 1000;

আমি কোনও মাইক্রোসফ্ট নির্দিষ্ট না ব্যবহার করে স্ট্যান্ডার্ড সি ++ ব্যবহার করে মেমরি অ্যাক্সেস লঙ্ঘনের ব্যতিক্রমটি ধরতে পারি?

উত্তর:


43

নাহ। আপনি যখন খারাপ কিছু করেন তখন সি ++ ব্যতিক্রম হয় না, এতে পারফরম্যান্স হিট হয় hit অ্যাক্সেস লঙ্ঘন বা শূন্য ত্রুটি দ্বারা বিভাজনের মতো জিনিসগুলি আপনি যে ভাষা-স্তরের জিনিসগুলি ধরতে পারেন তার চেয়ে "মেশিন" ব্যতিক্রমের মতো।


আমি জানি এটি HW ব্যতিক্রম, তবে মাইক্রোসফ্টের নির্দিষ্ট কীওয়ার্ডগুলি হ্যান্ডেল করে আছে (__ চেষ্টা করুন__ বাদে)?
আহমেদ

4
@ আহমেদ: হ্যাঁ, তবে আপনি যদি এগুলি ব্যবহার করেন তবে 'অসম্ভব' জিনিসগুলি ঘটতে পারে। উদাহরণস্বরূপ, কোডের AV রেখার পরে কিছু বিবৃতি ইতিমধ্যে কার্যকর করা হতে পারে, বা AV এর আগে বিবৃতি কার্যকর করা হয়নি।
হারুন

নিয়মিত চেষ্টা করুন ... ভিসি ++ এ ব্লক ধরুন কীভাবে এই জাতীয় ব্যতিক্রমগুলি পরিচালনা করতে সক্ষম হয় তা নীচে আমার উত্তরটি দেখুন।
ভোলডিমায়ার ফ্রিটস্কি

@ অ্যারন আপনি কি "অসম্ভব ঘটছে" অংশটি বিশদভাবে বর্ণনা করতে পারেন? এটি কি সংকলক এবং / অথবা সিপিইউ পুনর্নির্দিষ্ট নির্দেশের কারণে?
ওয়েপেং এল

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

108

এটি পড়ুন এবং কাঁদুন!

আমি এটি বের করেছিলাম। আপনি যদি হ্যান্ডলারের কাছ থেকে না ফেলে থাকেন তবে হ্যান্ডলারটি কেবল চালিয়ে যাবে এবং ব্যতিক্রমও তাই হবে।

যাদুটি ঘটে যখন আপনি নিজের ব্যতিক্রম ছুঁড়ে ফেলেন এবং এটি পরিচালনা করেন।

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <tchar.h>

void SignalHandler(int signal)
{
    printf("Signal %d",signal);
    throw "!Access Violation!";
}

int main()
{
    typedef void (*SignalHandlerPointer)(int);

    SignalHandlerPointer previousHandler;
    previousHandler = signal(SIGSEGV , SignalHandler);
    try{
        *(int *) 0 = 0;// Baaaaaaad thing that should never be caught. You should write good code in the first place.
    }
    catch(char *e)
    {
        printf("Exception Caught: %s\n",e);
    }
    printf("Now we continue, unhindered, like the abomination never happened. (I am an EVIL genius)\n");
    printf("But please kids, DONT TRY THIS AT HOME ;)\n");

}

দুর্দান্ত টিপ, বিশেষত কারণ __try / __ ব্যতীত এভি ধরবে না।
ফ্যাবিও সেকোনেলো

16
এটি জিসিসিতে কাজ করে না তবে ভিসি ++ এ কাজ করে তবে কেবল "ডিবাগ" বিল্ডে। একটি আকর্ষণীয় সমাধানের জন্য এখনও upvoting। সিগন্যাল হ্যান্ডলার কল করা হবে কিন্তু ব্যতিক্রম নিক্ষেপ করা হবে না।
নাটালি অ্যাডামস

4
এটি বহনযোগ্য কাজ করে না। যখন একটি সিগন্যাল হ্যান্ডলারটি স্ট্যাক ফ্রেমটি আহ্বান করা হয় এবং মুংটি রেজিস্টার করা হয় তখন কোনও সাধারণ ফাংশন স্ট্যাক ফ্রেম (এটি কিছু সিস্টেমে একই স্ট্যাক ব্যবহার নাও করতে পারে) হিসাবে একই হয় না। সিগন্যাল হ্যান্ডলারটি সক্রিয় হয়েছে তা চিহ্নিত করতে আপনি একটি পতাকা নির্ধারণ করতে পারেন সেরা is তারপরে সেই পতাকাটির জন্য আপনার কোড পরীক্ষায় এবং নিক্ষেপ করুন।
মার্টিন ইয়র্ক

4
এটির অপরিবর্তিত আচরণ প্রবর্তনের উচ্চ সম্ভাবনা রয়েছে। এটি পসআইএক্স-এ কাজ করার জন্য, কোনও বিকল্প সিগন্যাল স্ট্যাক ( sigaltstack) ইনস্টল করা উচিত নয় ( সি ++ ব্যতিক্রম আন-বাইন্ডিং বাস্তবায়ন এটির অনুমতি না দিলে) এবং অযৌক্তিক পদ্ধতিতে পরিচালিত প্রতিটি রানটাইম ফাংশন নিজেই সিগন্যাল-নিরাপদ হওয়া উচিত।
minmaxavg

4
আপনি যদি সিগন্যালটিতে ডিফল্ট হ্যান্ডলারটি ফিরে আসতে চান (এই ক্ষেত্রে SIGSEGV), জুস নিম্নলিখিতটি ব্যবহার করুন:signal(SIGSEGV, SIG_DFL);
কোকিকা

67

-> ক্যাচ (...) ব্লক ব্যবহার করে ভিজ্যুয়াল স্টুডিওতে যে কোনও ধরণের ব্যতিক্রম (শূন্য দ্বারা বিভাগ, অ্যাক্সেস লঙ্ঘন ইত্যাদি) ধরার খুব সহজ উপায় রয়েছে । একটি ছোটখাটো প্রকল্প সেটিংস টুইট করা যথেষ্ট। প্রকল্পের সেটিংসে কেবল / EHa বিকল্প সক্ষম করুন। প্রকল্পের বৈশিষ্ট্যগুলি দেখুন -> সি / সি ++ -> কোড জেনারেশন -> "এসইএইচ ব্যতিক্রম সহ হ্যাঁ" এর জন্য সক্ষম সি ++ ব্যতিক্রমগুলি সংশোধন করুন । এটাই!

বিশদটি এখানে দেখুন: http://msdn.microsoft.com/en-us/library/1deeycx5(v=vs.80).aspx


ভিজ্যুয়াল স্টুডিও। নেট 2003 এ তেমন কোনও সেটিং মান নেই, কেবলমাত্র "না" এবং "হ্যাঁ (/ ইএইচসিএস)" রয়েছে। এই সেটিংটি সক্ষম করার জন্য আপনার ভিজ্যুয়াল স্টুডিওর ন্যূনতম সংস্করণটি কী পরিষ্কার করতে হবে?
izogfif

লিঙ্কটি "ভিজ্যুয়াল স্টুডিও 2005" নির্দিষ্ট করে বলে মনে হচ্ছে
ড্রয় ডেলাানো

4
জিসিসি বা মিনজিডাব্লু দিয়ে কি হবে?
ব্যবহারকারী 1024

10

কমপক্ষে আমার পক্ষে, signal(SIGSEGV ...)অন্য উত্তরে উল্লিখিত পদ্ধতিটি ভিজ্যুয়াল সি ++ 2015 এর সাথে উইন 32 এ কার্যকর হয়নি । আমার জন্য কী কাজ করেছিল তা ব্যবহারে _set_se_translator()পাওয়া eh.h। এটি এর মতো কাজ করে:

ধাপ 1 ) নিশ্চিত করুন যে আপনি সক্ষম করুন Seh ব্যতিক্রমসমূহ (/ Eha) সঙ্গে হ্যাঁ মধ্যে প্রকল্প বিষয়বস্তু / সি ++ / কোড নির্মাণ / সি ++ ব্যতিক্রমসমূহ সক্ষম করুন যেমন দ্বারা উত্তর উল্লেখ করা হয়েছে, Volodymyr Frytskyy

পদক্ষেপ 2 ) কল করুন _set_se_translator(), নতুন ব্যতিক্রম অনুবাদকের জন্য একটি ফাংশন পয়েন্টার (বা ল্যাম্বদা) দিয়ে যাচ্ছেন । এটিকে অনুবাদক বলা হয় কারণ এটি মূলত কেবল নিম্ন-স্তরের ব্যতিক্রম নিয়ে যায় এবং এটিকে ধরা সহজতর কিছু হিসাবে পুনরায় নিক্ষেপ করে, যেমন std::exception:

#include <string>
#include <eh.h>

// Be sure to enable "Yes with SEH Exceptions (/EHa)" in C++ / Code Generation;
_set_se_translator([](unsigned int u, EXCEPTION_POINTERS *pExp) {
    std::string error = "SE Exception: ";
    switch (u) {
    case 0xC0000005:
        error += "Access Violation";
        break;
    default:
        char result[11];
        sprintf_s(result, 11, "0x%08X", u);
        error += result;
    };
    throw std::exception(error.c_str());
});

পদক্ষেপ 3 ) আপনার মত সাধারণত ব্যতিক্রমটি ধরুন:

try{
    MakeAnException();
}
catch(std::exception ex){
    HandleIt();
};

4
এই সাইটটিতে _set_se_translator () পদ্ধতিতে সহজ পদ্ধতিতে দম্পতি রয়েছে এবং আমার জন্য কাজ করে, msdn.microsoft.com/en-us/library/5z4bw5h5.aspx
দাশ

8

এই ধরণের পরিস্থিতি বাস্তবায়ন নির্ভর এবং ফলস্বরূপ ফাঁদে যাওয়ার জন্য এটি কোনও বিক্রেতার নির্দিষ্ট পদ্ধতি প্রয়োজন। মাইক্রোসফ্টের সাথে এতে এসইএইচ জড়িত, এবং * নিক্স একটি সংকেত জড়িত

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


4
সুতরাং আপনার পরামর্শটি এভি ব্যতিক্রমের কারণ কী তা জানতে হবে, তাই না?
আহমেদ

4
একেবারে। এভি'র আপনার কোডটিতে একটি বাগের প্রতিনিধি এবং ব্যতিক্রম ধরা কেবল সমস্যাটি আড়াল করবে।
জেয়ার্ডপাড়

4
স্পষ্ট করার জন্য, সি ++ স্ট্যান্ডার্ড অনির্ধারিত, অনির্ধারিত এবং বাস্তবায়ন সংজ্ঞায়িত মধ্যে পার্থক্য তৈরি করে। বাস্তবায়ন সংজ্ঞায়িত মানে বাস্তবায়ন অবশ্যই ঘটে তা নির্দিষ্ট করে। প্রশ্নের কোডটি অপরিবর্তিত, যার অর্থ যে কোনও কিছু ঘটতে পারে এবং প্রতিবারই আলাদা হতে পারে।
কিথবি

15
অ্যাক্সেস লঙ্ঘন ক্যাচ করা খারাপ ধারণা নয় - এটি ব্যবহারকারীর অভিজ্ঞতার জন্য ভাল। তবে, এক্ষেত্রে আমি একমাত্র অর্থবহ কাজটি হচ্ছি - বাগ রিপোর্টিং জিইউআইয়ের সাথে আরেকটি প্রক্রিয়া উত্সাহিত করুন এবং একটি বর্তমান প্রক্রিয়া ডাম্প তৈরি করার চেষ্টা করুন। কোনও প্রক্রিয়া তৈরি করা সর্বদা সফল অপারেশন। তারপরে, আমি আত্মহত্যা করতে টার্মিনেটপ্রসেস () করি।
Петров

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

8

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

DECLARE_EXCEPTION_CLASS(datatype_misalignment)
DECLARE_EXCEPTION_CLASS(breakpoint)
DECLARE_EXCEPTION_CLASS(single_step)
DECLARE_EXCEPTION_CLASS(array_bounds_exceeded)
DECLARE_EXCEPTION_CLASS(flt_denormal_operand)
DECLARE_EXCEPTION_CLASS(flt_divide_by_zero)
DECLARE_EXCEPTION_CLASS(flt_inexact_result)
DECLARE_EXCEPTION_CLASS(flt_invalid_operation)
DECLARE_EXCEPTION_CLASS(flt_overflow)
DECLARE_EXCEPTION_CLASS(flt_stack_check)
DECLARE_EXCEPTION_CLASS(flt_underflow)
DECLARE_EXCEPTION_CLASS(int_divide_by_zero)
DECLARE_EXCEPTION_CLASS(int_overflow)
DECLARE_EXCEPTION_CLASS(priv_instruction)
DECLARE_EXCEPTION_CLASS(in_page_error)
DECLARE_EXCEPTION_CLASS(illegal_instruction)
DECLARE_EXCEPTION_CLASS(noncontinuable_exception)
DECLARE_EXCEPTION_CLASS(stack_overflow)
DECLARE_EXCEPTION_CLASS(invalid_disposition)
DECLARE_EXCEPTION_CLASS(guard_page)
DECLARE_EXCEPTION_CLASS(invalid_handle)
DECLARE_EXCEPTION_CLASS(microsoft_cpp)

মূল শ্রেণিটি এই খুব দরকারী নিবন্ধ থেকে এসেছে:

http://www.codeproject.com/KB/cpp/exception.aspx


8
আমি দেখতে পাচ্ছি যে একটি মাইক্রোসফ্ট সংকলক ব্যবহার করা অবৈধ নির্দেশনা বা অ্যাক্সেস লঙ্ঘন হিসাবে একই আচরণ করা হয়। মজাদার.
ডেভিড থর্নলি

3

ব্যতিক্রম হ্যান্ডলিং প্রক্রিয়া নয়, তবে আপনি সি দ্বারা প্রদত্ত সিগন্যাল () প্রক্রিয়াটি ব্যবহার করতে পারেন

> man signal

     11    SIGSEGV      create core image    segmentation violation

কোনও নুল পয়েন্টারটিতে লেখা সম্ভবত একটি SIGSEGV সংকেতের কারণ হতে পারে


@ মাইমডামি পিক্সিক্স signal()স্ট্যান্ডার্ডের একটি অংশ। উইন্ডোজ পোস্টিক্স স্ট্যান্ডার্ডটি প্রয়োগ করে (লিনাক্স এবং ইউনিক্সের মতো)
মার্টিন ইয়র্ক

-1

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


7
অ্যাক্সেস লঙ্ঘন থেকে পুনরুদ্ধার করা সম্ভব হতে পারে। আপনি ডডি না হয়ে এবং সমাবেশ স্তরের নির্দেশনা নির্দেশক না রাখলে ইআইপি জাম্প ভয়েলেশন থেকে পুনরুদ্ধার কখনই সম্ভব নয়। তবে বাগের রিপোর্টিং জিইউআই বৈশিষ্ট্যটির জন্য অন্য প্রক্রিয়া তৈরি করার জন্য অ্যাক্সেস লঙ্ঘন ধরা ভাল good
Петров
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.