2015-11-04 7 views
6

मुझे "System.NullReferenceException: ऑब्जेक्ट संदर्भ किसी ऑब्जेक्ट के उदाहरण पर सेट नहीं किया जा रहा है।" मेरी रिलीज बिल्ड पर। मैंने एक नमूना आवेदन बनाया है जो मेरे उत्पादन कोड में क्या है इसका अनुकरण करता है।वीएस2015 सी ++/सीएलआई रिलीज में NullReferenceException

void Abc::LogService::Log(String^ message) 
{ 
    try 
    {  
     int ret = DoProcessing(message); 
     Exception^ ex; 
     if (ret == 0) 
     { 
      ex = gcnew ArgumentException("Processing done."); 
     } 
     else 
     { 
      ex = gcnew ArgumentNullException("message", "Null args"); 
     } 
     throw ex; 
    } 
    finally 
    { 
     //do someother thing. 
    } 
} 
ऊपर कोड के साथ

, यह रिपोर्ट होने के लिए अपवाद लाइन: at Abc.LogService.Log(String message) in logservice.cpp:line 19 जो कोड में throw ex; बयान से मेल खाती है।

.method public hidebysig instance void Log(string message) cil managed 
{ 
    // Code size  46 (0x2e) 
    .maxstack 4 
    .locals ([0] class [mscorlib]System.Exception V_0, 
      [1] class [mscorlib]System.Exception ex) 
    .try 
    { 
    IL_0000: ldarg.0 
    IL_0001: ldarg.1 
    IL_0002: call  instance int32 Abc.LogService::DoProcessing(string) 
    IL_0007: ldnull 
    IL_0008: stloc.1 
    IL_0009: brtrue.s IL_0018 
    IL_000b: ldstr  "Processing done." 
    IL_0010: newobj  instance void [mscorlib]System.ArgumentException::.ctor(string) 
    IL_0015: stloc.0 
    IL_0016: br.s  IL_0028 
    IL_0018: ldstr  "message" 
    IL_001d: ldstr  "Null args" 
    IL_0022: newobj  instance void [mscorlib]System.ArgumentNullException::.ctor(string, 
                        string) 
    IL_0027: stloc.0 
    IL_0028: ldloc.1 
    IL_0029: throw 
    IL_002a: leave.s IL_002d 
    } // end .try 
    finally 
    { 
    IL_002c: endfinally 
    } // end handler 
    IL_002d: ret 
} // end of method LogService::Log 

MSIL कोड से, यह पता चलता है कि बयान IL_0028 में, यह एक शून्य मान अप लोड करता है और बाद में एक बयान में फेंक कॉल:

इस कार्य के लिए रिलीज निर्माण में MSIL के रूप में लग रहा है। अजीब हिस्सा यह होता है कि यह तब होता है जब मेरे पास अंततः प्रयास करें। उपरोक्त कोड का डीबग बिल्ड ठीक काम करता है।

क्या यह वीएस2015 v140 टूलकिट में एक बग के रूप में ध्वनि करता है?

उत्तर

3

हां, यह एक अनुकूलक बग है। बहुत असामान्य, मैंने पहली बार सी ++/सीएलआई के लिए देखा है, एक ऐसी भाषा जहां जिटर को भारी उठाना है। ऐसा लगता है कि ex वैरिएबल को ट्राई-ब्लॉक के अंदर घोषित करके इसे प्रारंभिक गारंटी पर चकित करने के लिए ट्रिप किया जा रहा है। एक प्रवाह विश्लेषण बग की तरह लग रहा है।

/ओवर ड्राफ्ट के साथ संकलन से कम, एक वैकल्पिक हल कोशिश ब्लॉक से बाहर ले जाने के लिए चर है

void Log(String^ message) { 
    Exception^ ex; 
    try { 
     // etc... 
} 

भी काफी बेहतर MSIL उत्पादन, पूरी तरह से चर को नष्ट:

.method public hidebysig instance void Log(string message) cil managed 
{ 
    // Code size  41 (0x29) 
    .maxstack 4 
    .try 
    { 
    IL_0000: ldarg.0 
    IL_0001: ldarg.1 
    IL_0002: call  instance int32 Test::DoProcessing(string) 
    IL_0007: brtrue.s IL_0015 
    IL_0009: ldstr  "Processing done." 
    IL_000e: newobj  instance void [mscorlib]System.ArgumentException::.ctor(string) 
    IL_0013: br.s  IL_0024 
    IL_0015: ldstr  "message" 
    IL_001a: ldstr  "Null args" 
    IL_001f: newobj  instance void [mscorlib]System.ArgumentNullException::.ctor(string, 
                        string) 
    IL_0024: throw 
    IL_0025: leave.s IL_0028 
    } // end .try 
    finally 
    { 
    IL_0027: endfinally 
    } // end handler 
    IL_0028: ret 
} // end of method Test::Log 

अनुकूलक कीड़े चूसो, आप इसे connect.microsoft.com पर रिपोर्ट कर सकते हैं