Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
237 views
in Technique[技术] by (71.8m points)

compact framework - What are some techniques for troubleshooting very intermittent Access Violation on a Windows Mobile Device?

I have a large Compact Frameworks V2.0 application that in most cases works very well. On certain devices about once a day, a user receives a Native Error 0xC0000005 that is not caught with the standard managed Try/Catch block.

My application synchronizes with the server via ASMX calls at fixed intervals. The problem appears to occur during synchronization. There is considerable business logic in addition to the ASMX call that happens at the time of the synchronization, but 98% of that is managed code. I've reviewed all my P/Invokes and the applications native C++ libraries and at this point I'm about 95% certain that isn't where the problem is.

Since this only happens on certain devices and very infrequently (less than once a day) it's very difficult to isolate. I've instruemented my code and it appears as if it happens in random places within the application, so I suspect something is corrupting memory.

Any thoughts on how to troubleshoot this further would be appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

A 0xC0000005 is an access violation, so something is trying to read from or write to an address that it doesn't have rights to access. These tend to be really hard to find and experience is one of the best tools (well Platform Builder's debugger is really helpful too, but that's a whole separate avenue of debugging and requires experience that you probably don't have or you'd have already tried it). I find that logging tends to be less useful that subtractive coding - removing P/invoke calls with mock managed calls whenever possible.

Access violations in managed apps typically happen for one of these reasons:

  • You P/Invoke a native API passing in a handle to a managed object and the native API uses that handle. If you get a collection and compaction while the native API is running, the managed object may move and the pointer becomes invalid.
  • You P/Invoke something with a buffer that is too small or smaller than the size you pass in and the API overruns a read or write
  • A pointer (IntPtr, etc) you pass to a P/Invoke call is invalid (-1 or 0) and the native isn't checking it before use
  • You P/Invoke a native call and the native code runs out of memory (usually virtual) and isn't checking for failed allocations and reads/writes to an invalid address
  • You use a GCHandle that is not initialized or that somehow is pointing to an already finalized and collected object (so it's not pointing to an object, it's pointing to an address where an object used to be)
  • Your app uses a handle to something that got invalidated by a sleep/wake. This is more esoteric but certainly happens. For example, if you're running an application off of a storage card, the entire app isn't loaded into RAM. Pieces in use are demand-paged in for execution. This is all well and good. Now if you power the device off, the drivers all shut down. When you power back up, many devices simply re-mount the storage devices. When your app needs to demand-page in more program, it's no longer where it was and it dies. Similar behavior can happen with databases on mounted stores. If you have an open handle to the database, after a sleep/wake cycle the connection handle may no longer be valid.

You'll note the trend here that almost all of these are P/Invokes and that's no accident. It's quite difficult to get managed code to do this on its own.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...