开发者

COM interop failing in release mode

I have a console app which makes a call to the windows search using a ComImport. While this works fine in debug mode...the console application crashes in release mode. What could be the problem?

[ComImport]
    [Guid("9DAA54E8-CD95-4107-8E7F-BA3F24732D95")]
    [ClassInterface(ClassInterfaceType.None)]
    [TypeLibType(TypeLibTypeFlags.FCanCreate)]
    public class WordBreaker : IWordBreaker
    {
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        public virtual extern bool Init([In] bool query, [In] uint maxTokenSize);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime开发者_StackOverflow社区)]
        public virtual extern void BreakText([In, MarshalAs(UnmanagedType.LPStruct)] TEXT_SOURCE textSource,
            [In] IWordSink wordSink, [In] IPhraseSink phraseSink);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        public virtual extern void ComposePhrase([In, MarshalAs(UnmanagedType.LPWStr)] string noun, [In] uint nounLen,
            [In, MarshalAs(UnmanagedType.LPWStr)] string modifier, [In] uint modifierLen,
            [In] uint attachmentType, [Out] out IntPtr phrase, [In, Out] ref uint phraseLen);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        public virtual extern IntPtr GetLicenseToUse();
    }

The code fails in release mode while accessing WordBreaker.BreakText function.

It is being used in my code as shown below

if (!string.IsNullOrWhiteSpace(text))
                try
                {
                    IWordBreaker breaker = new WordBreaker();
                    bool reqLicense = breaker.Init(query, 256);
                    if (reqLicense)
                    {
                        IntPtr lic = breaker.GetLicenseToUse();
                        string licText = Marshal.PtrToStringUni(lic);
                    }
                    TEXT_SOURCE source = new TEXT_SOURCE();
                    source.fillTextBuffer = FillTextBuffer;
                    source.buffer = text;
                    source.cur = 0;
                    source.end = (uint)(text.Length);
                    breaker.BreakText(source, new WordSink(result), null);
                }
                catch (Exception ex)
                {
                    Console.Out.WriteLine(ex.ToString());
                    //log4net.LogManager.GetLogger(typeof(WindowsIntegration)).Error("BreakText", ex);
                }
            var resultWithoutNoise = NoiseWord.Remove(result);
            return resultWithoutNoise;
        }

The crash occurs in breaker.BreakText exactly The BreakText function is called many times (between 500 to 7000 times) before the app crashes.

The crashdump says the following about exception information The thread tried to read from or write to a virtual address for which it does not have the appropriate access. note: I am not using any threads in my code.


The code needs at least one thread which is what the error referred to. As for the type of crash, it's essentially an access violation, either down to a null pointer/object reference (in native code) or a buffer over run. Check what values. string. lengths, etc that you're passing in at the point it fails.


This looks like a case where the garbage collector is moving text to another location so the address recorded in source.buffer is no longer valid. You haven't included the source which declares TEXT_SOURCE so I can't comment on that. But the declaration of BreakText is not correct. MarshalAs(UnmanagedType.LPStruct) should not be used there. UnmanagedType.LPStruct is only supported for one specific case: treating a System.Guid value type as an unmanaged GUID with an extra level of indirection. See http://blogs.msdn.com/b/adam_nathan/archive/2003/04/23/56635.aspx and How do I marshal a structure as a pointer to a structure?.


If you're not able to reproduce the issue and it only does it in release I would highly suggest you add logging to narrow down your problem.

When you've narrowed down your problem I would edit your post above to include the more detailed information about the crash.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜