2009-11-11 15 views
12

में .NET सामान्य भाषा रनटाइम (सीएलआर) को क्रैश कैसे करें Java VM को लक्षित करने वाला एक समान प्रश्न है लेकिन मुझे .NET के लिए कोई प्रश्न नहीं मिला है (अगर मैं कुछ खो रहा था तो कृपया बंद करें और डुप्लिकेट के रूप में चिह्नित करें)।शुद्ध .NET

तो क्या यह बिना किसी अप्रबंधित इंटरऑप के संभव है? और क्रैश होने के साथ मेरा मतलब है कि एक वास्तविक "xxx.exe ने काम करना बंद कर दिया है" स्टैक ओवरफ्लो- या आउटऑफमेमरी अपवाद नहीं।

मुझे लगता है कि यह संभव नहीं है, वीएम में एक बग मारने के अलावा।

+2

.NET CLR के पूरे मुद्दे सार करने के लिए कंप्यूटर से दूर है, CLR के अंदर ढेर अतिप्रवाह और अन्य कीड़े रखने और (यहां तक ​​कि एक गाड़ी ओएस के साथ) अपने भौतिक कंप्यूटर दुर्घटनाग्रस्त नहीं – Earlz

+1

ऐसी बात है, तो संभव है, क्या यह परिभाषा के अनुसार "वीएम स्वयं में बग" श्रेणी में नहीं आता है? –

+0

हां .. जब तक आप महत्वपूर्ण फाइलों को हटाने और सीएलआर रनटाइम – Earlz

उत्तर

15

अच्छा ... आप "शुद्ध .NET" को कैसे परिभाषित करेंगे? मैं CLR2/प्रतिनिधि/GCHandle/सरणी के साथ खेला जाता है जब मैं "JVM दुर्घटना करने के लिए कैसे" पोस्ट पढ़ा है, और कुछ इस तरह के साथ आया था:

using System; 
using System.Reflection; 
using System.Runtime.InteropServices; 

namespace TestCLR2Crash { 
     static void Main(string[ ] args) { 
      // declare a delegate that refers to a static method, 
      // in this case it's a static method generated from the 
      // anonymous delegate. 
      Action action = delegate() { }; 

      // "generate" code into an array of uint 
      var fakeDelegate = new uint[ ] { 
       // dummy values 
       0x00000000, 0x00000000, 
       // fake _methodPtrAux 
       0x00000000, 
       // native code/string 
       0x6AEC8B55, 0x2FD9B8F5, 0xD0FF7C81, 0x006A006A, 
       0x00E81F6A, 0x83000000, 0x50102404, 0x81CC5DBA, 
       0x8BD2FF7C, 0x47C35DE5, 0x74656572, 0x73676E69, 
       0x6F726620, 0x6567206D, 0x6172656E, 0x20646574, 
       0x65646F63, 0x00000A21 
      }; 

      // fill in the fake _methodPtrAux, 
      // make it point to the code region in fakeDelegate 
      var handle = GCHandle.Alloc(fakeDelegate, GCHandleType.Pinned); 
      var addr = handle.AddrOfPinnedObject(); 
      const int sizeOfUInt32 = sizeof(uint); // 4 
      const int indexOfCode = 3; 
      fakeDelegate[ 2 ] = Convert.ToUInt32(addr.ToInt32() + sizeOfUInt32 * indexOfCode); 

      var targetInfo = typeof(Action) 
       .GetField("_target", BindingFlags.NonPublic | BindingFlags.Instance); 
      targetInfo.SetValue(action, fakeDelegate); 
      action();  // Greetings from generated code! 
      Console.WriteLine("Greetings from managed code!"); 

      handle.Free(); 
     } 
    } 
} 

यह केवल CLR2 साथ पर 32-बिट Windows XP काम करने के लिए जाना जाता है x86 पर; और विस्टा और विंडोज 7 और इसी तरह के साथ काम नहीं करने के लिए भी जाना जाता है, जहां डीईपी + एएसएलआर डिफ़ॉल्ट रूप से चालू होता है।

उपरोक्त कोड के बारे में मजाक का मुद्दा यह है कि यह स्पष्ट रूप से असुरक्षित कोड का उपयोग नहीं करता है (हालांकि GCHandle.Alloc (..., GCHandleType.Pinned) सुरक्षा विशेषाधिकार की मांग करता है), फिर भी यह नकली सरणी को प्रबंधित करता है प्रतिनिधि उदाहरण, और सरणी के भीतर x86 मशीन कोड में कॉल करता है। कोड स्वयं शुद्ध सी # है, यदि आप एम्बेडेड x86 कोड को कुछ "विदेशी भाषा" के रूप में नहीं मानते हैं ;-) असल में यह स्थिर तरीकों पर सीएलआर 2 के प्रतिनिधियों के आंतरिक कार्यान्वयन का उपयोग करता है, कि वास्तव में प्रतिनिधि के कुछ निजी सदस्य वास्तव में हैं आंतरिक संकेतक मैंने x86 कोड को एक सरणी में भर दिया, जिसे प्रबंधित ढेर पर आवंटित किया गया है। इसलिए इसे काम करने के लिए, डीईपी सक्षम नहीं होना चाहिए, या हमें उस मेमोरी पेज पर निष्पादन विशेषाधिकार प्राप्त करने के लिए कुछ और तरीका ढूंढना होगा।

86 कोड इस तरह है: (छद्म MASM वाक्य रचना में)

55    push ebp 
8BEC   mov ebp,esp 
6A F5   push -0B       ; /DevType = STD_OUTPUT_HANDLE 
B8 D92F817C  mov eax,KERNEL32.GetStdHandle ; | 
FFD0   call eax       ; \GetStdHandle 
6A 00   push 0       ; /pReserved = NULL 
6A 00   push 0       ; |pWritten = NULL 
6A 1F   push 1F       ; |CharsToWrite = 1F (31.) 
E8 00000000  call <&next_instruction>   ; | 
830424 10  add dword ptr ss:[esp],10  ; |Buffer 
50    push eax       ; |hConsole 
BA 5DCC817C  mov edx,KERNEL32.WriteConsoleA ; | 
FFD2   call edx       ; \WriteConsoleA 
8BE5   mov esp,ebp 
5D    pop ebp 
C3    ret 

यह एक व्यवहार CLI द्वारा निर्दिष्ट नहीं है, और इस तरह मोनो के रूप में अन्य CLI कार्यान्वयन पर काम नहीं करेगा। हालांकि मोनो पर समान तर्क चलाने के अन्य तरीके हैं, पहले से ही उबंटू 9.04 डब्ल्यू/मोनो 2.4 पर कोशिश की और काम किया।

मैं इसके बारे में यहाँ एक ब्लॉग पोस्ट ने लिखा है: http://rednaxelafx.javaeye.com/blog/461787

यह चीनी में है, लेकिन वहाँ कोड के बहुत सारे जो व्याख्या करनी चाहिए मैं क्या किया है। ब्लॉग पोस्ट के अंत में, एक ही चाल का उपयोग करके मैंने कुछ उदाहरण दिखाए कि आप चीजों को गलत बनाने के लिए ऊपर दिए गए कोड को कैसे बदल सकते हैं, जैसे कि SEHException प्राप्त करना।

+0

मुझे अभी भी अनिश्चित है कि यह "शुद्ध .net" है - परिभाषा धुंधली हो जाती है। हालांकि, यह निश्चित रूप से एक बहुत अच्छा विचार +1 है! –

-1

मुझे पता है कि आप अपने पूरे पीसी को .NET के साथ क्रैश कर सकते हैं। लेकिन इसमें एक अंतहीन पाश और रीयलटाइम प्रक्रिया प्राथमिकता शामिल है ...

+0

प्रक्रिया प्राथमिकता - अच्छा विचार। लेकिन क्या हम प्रक्रिया के अंदर से प्रक्रिया प्राथमिकता बदल सकते हैं? या हम हमारी तुलना में उच्च प्राथमिकता के साथ, एक और प्रक्रिया को ट्रिगर कर सकते हैं? अच्छा .... देखते हैं ... –

+0

बस कोशिश की: एक कार्यप्रणाली प्रक्रिया अंतहीन लूपिंग और वस्तुओं को तत्काल कर रही है जबकि इसे ProcessPriorityClass का उपयोग करके किसी अन्य प्रक्रिया द्वारा शुरू किया गया था।रियल टाइम। मशीन का प्रदर्शन खराब हो गया है, यकीन है, लेकिन यह दुर्घटनाग्रस्त नहीं है। –

+0

आप इसे Process.GetCurrentProcess() का उपयोग कर सेट कर सकते हैं। प्रक्रिया प्राथमिकता या ऐसा कुछ। लेकिन मेरे पास मिश्रित परिणाम हैं। उदाहरण के लिए पूरी तरह से मेरी मशीन पूरी तरह से जम गई। मुझे नहीं पता कि यह मायने रखता है लेकिन मैं हमेशा व्यवस्थापक के रूप में लॉग इन करता हूं। – Vivelin

2

ओरेन ईनी ने .net फ्रेमवर्क में एक बग की खोज की जिसके कारण 'निष्पादनइंजिन अपवाद' - मूल रूप से रनटाइम का एक क्रैश हुआ।

आप यहाँ इसके बारे में पढ़ सकते हैं (माइक्रोसॉफ्ट कनेक्ट):

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=384781

और बग के 'बंद' राज्य के बावजूद - यह अभी तक तय नहीं है।

+0

बग रिपोर्ट बंद कर दी गई थी क्योंकि उसे एक कामकाज मिला ... इसलिए एमएस ने रिपोर्ट बंद कर दी और कभी भी इस मुद्दे को ठीक नहीं किया क्योंकि किसी और को भी कोई समस्या नहीं थी। –

+0

... और समस्या स्वयं ही प्रदान किए गए समाधान को देखे बिना अंधेरे में रहती है। हालांकि, इसे "सीएलआर में बग" के रूप में भी वर्गीकृत किया जाएगा –

2

मैंने आज ही ऐसा किया है। मैं एक बड़े .NET प्रोजेक्ट के सेटअप का परीक्षण कर रहा था। कुछ इंटरफेस युक्त एक असेंबली गायब थी और exe बस काम करना बंद कर देता है। रनटाइम द्वारा कोई अपवाद नहीं पकड़ा गया था।

तुम्हें यकीन है कि वहाँ क्रम में एक और भी अधिक कीड़े हो सकता है - बस कोड की लाइनों के लाखों लोगों की गिनती ...

1

मैंने देखा है जावा प्रोग्राम एक न के बराबर वर्ग लोड करके JVM दुर्घटना और ClassNotFoundError को अनदेखा करते हुए, फिर निष्पादित करना जारी रखें जैसे कुछ भी नहीं हुआ। शायद आप .NET क्लास को गतिशील रूप से लोड करते समय कुछ ऐसा ही कर सकते हैं।

+0

चूंकि हम कक्षाओं में कक्षाएं लोड नहीं कर सकते हैं, लेकिन बस विधानसभाएं थोड़ा अलग होती हैं। जब हम एक असेंबली लोड करने में असफल रहे और अपवाद को निगल लिया, तो केवल एक चीज जिसे हम कोशिश कर सकते थे, प्रतिबिंब द्वारा कक्षा और/या विधि को ढूंढना है। लेकिन फिर सबसे बुरी चीज एक और अपवाद है, या तो कुछ प्रतिबिंब से संबंधित कुछ (उदा। TypeLoadException) या एक NullReferenceException जब कुछ चर एक असेंबली लोड करने के बाद शून्य नहीं होने की उम्मीद है। इसे समेटने के लिए: मुझे इसके लिए .NET में कोई मौका नहीं दिखता है। और यदि आप सही हैं तो निश्चित JVM शायद इस पर छोटी है। –

+0

यह एक सूर्य जेवीएम था, लेकिन कुछ साल पहले, शायद लगभग 2.x संस्करण। –

-1

कुछ सी # कोड है कि तकनीकी रूप से सही वैध नेट प्रोग्राम के रूप में नहीं चलेंगे। इसमें एक खाली विधि ओवरलोड करने के साथ इंटरफ़ेस के साथ कुछ है लेकिन मुझे वास्तव में याद नहीं है।

0

आप इस कोड को/clr के साथ संकलित कर सकते हैं: शुद्ध और लिंकर बल शुद्ध विकल्प भी है।

हालांकि, यह रनटाइम विफलता की तरह दिखता है;

(1388.5e4): Access violation - code c0000005 (!!! second chance !!!) eax=8d00fea5 ebx=00000000 ecx=00253e50 edx=00253e50 esi=022ad3cc edi=00253e50 eip=6ae965c5 esp=0020edbc ebp=0020edc8 iopl=0 nv up ei pl zr na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b
efl=00010246 * WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\eb4e1e70734f6efb9c7de7ec5f452c9e\mscorlib.ni.dll mscorlib_ni+0x9365c5: 6ae965c5 ff10
call dword ptr [eax]
ds:002b:8d00fea5=????????

भले ही आप/CLR के साथ संकलन: शुद्ध या/clr: सुरक्षित, और छवि यह इस तरह के रूप में आत्म का प्रतिनिधित्व करता है, यह केवल सत्यापनकर्ता इस बग (संकलक बग) को पकड़ने की वजह से पूर्ण विश्वास में काम करेंगे।

namespace Settings 
{ 
    public ref class RefType 
    {  
    public: 
     unsigned int I; 
     String^ S;  
     unsigned long L; 
    }; 
    public ref class aUseTemplate 
    { 
    public: 
     void CallTemplate() 
     { 
      array<RefType^>^ refarr = gcnew array<RefType^>(20); 
      for(int i=0; i < 20; i++) 
      { 
       RefType^ rt = gcnew RefType(); 
       rt->I = 0x42424242; 
       rt->L = 0x33333333; 
       refarr[i] = rt; 
      } 

      HasTemplate(refarr); 
     } 
     template<typename T> void HasTemplate(T input) 
     { 
      for each(T% x in input) 
       Console::WriteLine(x); 
     } 
    }; 
} 

यह peverify की उत्पादन है, जो पूरे पीई फ़ाइल को पार्स से है, इस त्रुटि जब तक क्रम, के रूप में सत्यापनकर्ता JIT'er साथ काम करता इस विधि में कॉल करता है और आलसी के बारे में यह सत्यापित नहीं है पता नहीं ।

[IL]: Error: [C:\Users\files\Documents\Visual Studio 2010\Projects\testCli\bin\Release\PureSettings.dll : Settings.aUseTemplate::HasTemplate^>][off set 0x00000017][found ref 'Settings.RefType'][expected address of ref ] Unexpected type on the stack. 1 Error(s) Verifying PureSettings.dll

आप यहाँ सत्यापनकर्ता को बायपास कर सकता है, तो यह CLR में एक विशाल बग हो सकता है और एक unprivilaged प्रक्रिया से आप कोड निष्पादन देना होगा।

यहां एमएसआईएल है;

IL_000d: bge.s  IL_0021 
    IL_000f: ldloc.1 
    IL_0010: ldloc.0 
    IL_0011: ldelem.ref 
    IL_0012: castclass Settings.RefType 
    IL_0017: stloc.2 
    IL_0018: ldloc.2 
    IL_0019: ldind.ref 
    IL_001a: call  void [mscorlib]System.Console::WriteLine(object) 
    IL_001f: br.s  IL_0006 
    IL_0021: ret 

बग ऑफसेट पर है, IL_19।

यदि आप सीएएस या किसी अन्य प्रकार के सुरक्षित मोड के तहत चल रहे हैं, तो यह कोड प्रसिद्ध "कोड रनटाइम को अस्थिर कर सकता है" अपवाद उत्पन्न करेगा।

2

असुरक्षित कोड या प्रतिनिधियों का उपयोग करने की आवश्यकता के बिना (अगर मुझे यह स्वीकार करना होगा कि यह आपके सीएलआर को क्रैश करने का एक बहुत अच्छा तरीका है), तो आप क्रैश करने के लिए .NET को मजबूर करने के लिए सरल मार्शल फ़ंक्शंस का उपयोग कर सकते हैं।

using System; 
using System.Runtime.InteropServices; 

namespace Crash 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      IntPtr p = Marshal.AllocHGlobal(1); 
      for (int i = 0; i < 10000000; ++i) 
      { 
       p = new IntPtr(p.ToInt64() + 1); 
       Marshal.WriteByte(p, 0xFF); 
      } 
     } 
    } 
} 

इसके अलावा, हमेशा जीसीएचंडल का उपयोग करके, त्रुटि की तरह स्मृति पहुंच उल्लंघन का कारण बन जाएगा।

using System; 
using System.Runtime.InteropServices; 

namespace Crash 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      GCHandle.FromIntPtr(new IntPtr(32323)); 
     } 
    } 
} 
+0

मुझे आखिरी, छोटी और प्यारी पसंद है। इसे मेरे क्रैश परीक्षण के लिए इस्तेमाल किया। – SilverSideDown

संबंधित मुद्दे