andydeforest Posted May 18, 2016 Report Share Posted May 18, 2016 (edited) Hello, My program usually runs fine for about 20 minutes, then crashes from a System.AccessViolationException. I tried rebuilding the program with x86 architecture targeted as was suggested on Stack Overflow, but the problem still persists. Here are the relevant parts of the code: private bool fsuipc_state = true; private Timer updateInfoTimer; public FlightForm(User u, Flight f) { InitializeComponent(); try { FSUIPCConnection.Open(); this.fsuipc_state = true; } catch(FSUIPCException e) { if(e.FSUIPCErrorCode == FSUIPCError.FSUIPC_ERR_SENDMSG) { this.log("Error connecting to FSUIPC"); this.fsuipc_state = false; } } this.showFsuipcState(); // This timer updates form info with FSUIPC data this.updateInfoTimer = new Timer(); this.updateInfoTimer.Tick += new EventHandler(this.updateInfoTimerTick); this.updateInfoTimer.Interval = 1000; this.updateInfoTimer.Start() } private void updateInfoTimerTick(object sender, EventArgs e) { try { FSUIPCConnection.Process(); // This is where the AccessViolationException occurs if(!this.fsuipc_state) { this.log("Reconnected to FSUIPC"); } this.fsuipc_state = true; this.showFsuipcState(); // Various FSUIPC offsets processed here } catch(FSUIPCException ex) { if(ex.FSUIPCErrorCode == FSUIPCError.FSUIPC_ERR_SENDMSG) { this.log("Connection to FSUIPC lost"); this.fsuipc_state = false; this.showFsuipcState(); } } catch(Exception) { // catch-all } } The updateInfoTimerTick fires every 1 second and updates my UI with FSUIPC offsets. Everything runs smoothly until the Exception. Regards, Andrew Edited May 18, 2016 by andydeforest Link to comment Share on other sites More sharing options...
andydeforest Posted May 18, 2016 Author Report Share Posted May 18, 2016 I checked the app's logs, and I'm getting this every 2 minutes: [12:24 PM]: FSUIPC Error #9: FSUIPC_ERR_NOTOPEN. The connection to FSUIPC is not open. [12:26 PM]: FSUIPC Error #9: FSUIPC_ERR_NOTOPEN. The connection to FSUIPC is not open. [12:28 PM]: FSUIPC Error #9: FSUIPC_ERR_NOTOPEN. The connection to FSUIPC is not open. Link to comment Share on other sites More sharing options...
Paul Henty Posted May 19, 2016 Report Share Posted May 19, 2016 Hi Andrew, What version of the DLL are you using? (You can check the properties of the DLL in the windows explorer). Also can you confirm you are declaring the Offset variables at the Form (class) level and not in updateInfoTimerTick(). Paul Link to comment Share on other sites More sharing options...
andydeforest Posted May 19, 2016 Author Report Share Posted May 19, 2016 Hi Paul, Thanks for the prompt reply. I'm using 2.4.0.0 of the DLL. I tried it with the 3.0 RC1 and had the same issue. The offsets are declared like this: public partial class FlightForm : Form { private Offset<int> ias = new Offset<int>(0x02BC); private Offset<int> tas = new Offset<int>(0x02B8); private Offset<int> gs = new Offset<int>(0x02B4); public FlightForm(User u, Flight f) { InitializeComponent(); // other program logic } private void updateInfoTimerTick(object sender, EventArgs e) { try { FSUIPCConnection.Process(); // GS: Ground Speed, as 65536*metres/sec double groundspeed = this.metersSecToKnots((double)gs.Value / 65536); } catch(FSUIPCException ex) { if(ex.FSUIPCErrorCode == FSUIPCError.FSUIPC_ERR_SENDMSG) { FSUIPCConnection.Close(); } } } catch(Exception) { } } I omitted most of the program logic for clarity. I just wanted to give you an idea of how I do things. Offsets are defined as class variables, then I access them in the updateInfoTimerTick() method after calling FSUIPCConnection.Process(). Link to comment Share on other sites More sharing options...
Paul Henty Posted May 19, 2016 Report Share Posted May 19, 2016 Your code looks fine. Please can you try again with the attached DLL. I've included the debug file (.pdb) which should also be extracted and placed in the same folder as the DLL. When you get the exception again, this should now give at least the line number and file name from the DLL source code in the exception details. Ideally I'm looking for a full call stack that contains all the internal calls in the dll. Can you paste the exception info here with the call stack. I'm not really sure where in the Process() method this could be happening at the moment. Thanks, Paul FSUIPCClient3.0_RC1.zip Link to comment Share on other sites More sharing options...
andydeforest Posted May 19, 2016 Author Report Share Posted May 19, 2016 (edited) Hi Paul, Here's the stack trace: System.AccessViolationException was unhandled HResult=-2147467261 Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt. Source=mscorlib StackTrace: at System.Runtime.InteropServices.Marshal.CopyToNative(Object source, Int32 startIndex, IntPtr destination, Int32 length) at System.Runtime.InteropServices.Marshal.Copy(Int32[] source, Int32 startIndex, IntPtr destination, Int32 length) at FSUIPC.FSUIPCConnection.Process(Byte ClassInstance, IEnumerable`1 GroupNames) in C:\Dev\FsuipcClient\fsuipcClient\fsuipcClient\fsuipcConnection.cs:line 777 at FSUIPC.FSUIPCConnection.Process(Byte ClassInstance, String GroupName) in C:\Dev\FsuipcClient\fsuipcClient\fsuipcClient\fsuipcConnection.cs:line 597 at FSUIPC.FSUIPCConnection.Process() in C:\Dev\FsuipcClient\fsuipcClient\fsuipcClient\fsuipcConnection.cs:line 558 at IntelliCARS.FlightForm.updateInfoTimerTick(Object sender, EventArgs e) in e:\DropBox\c#\IntelliCARS\IntelliCARS\FlightForm.cs:line 174 at System.Windows.Forms.Timer.OnTick(EventArgs e) at System.Windows.Forms.Timer.TimerNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.RunDialog(Form form) at System.Windows.Forms.Form.ShowDialog(IWin32Window owner) at System.Windows.Forms.Form.ShowDialog() at IntelliCARS.IntelliCARS.flyFlightButton_Click(Object sender, EventArgs e) in e:\DropBox\c#\IntelliCARS\IntelliCARS\AcarsForm.cs:line 182 at System.Windows.Forms.Control.OnClick(EventArgs e) at System.Windows.Forms.Button.OnClick(EventArgs e) at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ButtonBase.WndProc(Message& m) at System.Windows.Forms.Button.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.RunDialog(Form form) at System.Windows.Forms.Form.ShowDialog(IWin32Window owner) at System.Windows.Forms.Form.ShowDialog() at IntelliCARS.LoginForm.loginButton_Click(Object sender, EventArgs e) in e:\DropBox\c#\IntelliCARS\IntelliCARS\LoginForm.cs:line 45 at System.Windows.Forms.Control.OnClick(EventArgs e) at System.Windows.Forms.Button.OnClick(EventArgs e) at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ButtonBase.WndProc(Message& m) at System.Windows.Forms.Button.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.Run(Form mainForm) at IntelliCARS.Program.Main() in e:\DropBox\c#\IntelliCARS\IntelliCARS\Program.cs:line 16 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException: Edited May 19, 2016 by andydeforest Link to comment Share on other sites More sharing options...
Paul Henty Posted May 19, 2016 Report Share Posted May 19, 2016 Thanks for the call stack, I can see where the problem is now. I can't figure out why though. The DLL is trying to write to the FSUIPC shared memory file but it's being refused. It's the same memory area every time so I can't see why it's going wrong after 20 mins. My only guess at the moment is that the file is overflowing somehow. Can you get some more info for me... when this exception is thrown and it drops into debug mode, can you paste the following into the Immediate window and press return. Then show me the resulting lines. FSUIPCConnection.Statistics.processLast Thanks, Paul Link to comment Share on other sites More sharing options...
Pete Dowson Posted May 19, 2016 Report Share Posted May 19, 2016 Could either the application or FS be running "as administrator" -- i.e. on a different privilege level? Mind you, the OP did say "my program usually runs fine for about 20 minutes " so neither are suddenly going to change levels. Pete Link to comment Share on other sites More sharing options...
andydeforest Posted May 19, 2016 Author Report Share Posted May 19, 2016 I've found that 20 minutes isn't entirely accurate. Last night, I was trying to reproduce the error and my app ran fine for an hour before finally crashing. Today it took 10 minutes. So it's kind of all over the place. Anyway, here is the info you requested Paul: {FSUIPC.StatsProcess} BytesRead: 8.0 bytesRead: 8.0 bytesWritten: 0.0 BytesWritten: 0.0 fsuipcMemoryFileSizeBytes: 40.0 FsuipcMemoryFileSizeBytes: 40.0 groupsProcessed: {string[1]} GroupsProcessed: {string[1]} GroupsProcessedString: "~SystemOffsets~" OffsetsCount: 2.0 offsetsCount: 2.0 offsetsReadCount: 2.0 OffsetsReadCount: 2.0 OffsetsWriteCount: 0.0 offsetsWriteCount: 0.0 TimeForIPC: 22.0012 timeForIPC: 22.0012 TimeForProcessCall: 22.0012 timeForProcessCall: 22.0012 Link to comment Share on other sites More sharing options...
Paul Henty Posted May 20, 2016 Report Share Posted May 20, 2016 This is puzzling. The last successful group that was process()ed before the crash was "~SystemOffsets~". This group is only used internally in the DLL during the Open() connection process - i.e. calling FSUIPCConnection.Open(). I would not have expected to see this after 10 mins of operation because normally you just Open() at the start of the application and Close() at the end. I see from the stack trace you are opening this form from another form. Has any other form previously opened the FSUIPC connection? If so you don't need to open it again on this form. Once it's open it's open everywhere as it's a static class. At the moment I suspect there's some problem involving opening the connection too many times or maybe another thread is trying to open it at the same time as this form is trying to Process(). I'll be happy to take a look at your code if you don't mind sending me the whole project. It might be easier if I can debug it and my DLL here. Just attach it in a private message or send me a link. Otherwise, try and find out where the Opens are being called, or maybe paste some code snippets of the FSUIPC Open()s, and the code that opens the various forms. Paul Link to comment Share on other sites More sharing options...
andydeforest Posted May 20, 2016 Author Report Share Posted May 20, 2016 Paul, Thanks for the insight, that's exactly what's happening. I'm going to completely rework the logic tonight and see if that fixes anything before I bother you with my code. In the mean time, what is the proper way to check and make sure FSUIPC (and FSX/P3D) is still running each time updateInfoTimerTick() fires? I'm trying to make my program robust enough so that if FSX/P3D crashed, I can pause the app and reconnect once the simulator is repoened. Link to comment Share on other sites More sharing options...
Paul Henty Posted May 20, 2016 Report Share Posted May 20, 2016 It looks like you're already doing the right thing in that regard. Whenever you call Process() you need to catch any FSUIPCExceptions that arise. The FSUIPCError.FSUIPC_ERR_SENDMSG error means the connection was lost because the flight sim closed or has crashed. When this happens you should also stop that particular timer ticking so you don't keep trying to process() on the bad connection. Once your app is 'paused' you can either provide the user with a way to reconnect manually, or if you want it more automatic, have another timer (maybe every 2-5 seconds) that keeps trying to open the connection again. When it's successful (i.e. Open() didn't throw an Exception) you can stop that timer and start the main one again. Paul Link to comment Share on other sites More sharing options...
andydeforest Posted May 20, 2016 Author Report Share Posted May 20, 2016 Hi Paul, Thanks for all the help. I completely removed the previously-opened FSUIPCConnection from the other form and it seems to have solved the issue, so it looks like there was some overlap between the two connections causing issues. Thanks again, Andrew Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now