Jump to content
The simFlight Network Forums

Recommended Posts

Posted (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 by andydeforest
Posted

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.

 

Posted

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

 

Posted

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().

 

Posted

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

Posted (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 by andydeforest
Posted

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

 

Posted

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

 

Posted

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

 

Posted

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

Posted

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.

Posted

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

Posted

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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.