Memory objects getting lost

Sometimes Sanderling will stop finding or returning memory objects. This morning, after an hour of running, I found it returning null for modules that are present. It also seems to happen on other elements. Docking didn’t help. I have to restart Sanderling. Does anyone else find this? Is there anything that can be done to stop this, or know it has happened and reset things? (Just a moment ago it started returning null for the overview columns when they are clearly visible.)

Here’s some of the code, with some removed for OpSec:

	class Program
	{
		const int MeasurementTimeDistance = 300;
		static void SampleRun()
		{
			var eveOnlineClientProcessId = Extension.GetEveOnlineClientProcessId();

			if (null == eveOnlineClientProcessId)
			{
				Console.WriteLine("reading eve online client process id failed.");
				return;
			}
			var sensor = new Sensor();

			for (; ; )
			{
				var stopwatch = new System.Diagnostics.Stopwatch();
				string totalTime;
				stopwatch.Start();
				var response = sensor?.MeasurementTakeNewRequest(eveOnlineClientProcessId.Value);
				stopwatch.Stop();
				totalTime = stopwatch.ElapsedMilliseconds.ToString();
				if (null == response)
					continue;
				else
					MeasurementReceived(response?.MemoryMeasurement);
				Thread.Sleep(MeasurementTimeDistance);
			}
		}

		static public void MeasurementReceived(BotEngine.Interface.FromProcessMeasurement<IMemoryMeasurement> measurement)
		{
			string hostUsername = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
			string hostUsernameSanitized = hostUsername.Replace("\\", "|");
			string[] arrHostUser = hostUsernameSanitized.Split('|');
			string hostName = arrHostUser[1];
			string LocalInipath = "C:\\Users\\" + hostName + "\\AppData\\Local\\Macrolab\\Eve Pilot\\Scripts\\MiningDrones\\Sanderling.ini";
			System.IO.File.WriteAllText(LocalInipath, string.Empty);
			var parser = new FileIniDataParser();
			IniData data = parser.ReadFile(LocalInipath);
			var currentShield = measurement?.Value?.ShipUi?.HitpointsAndEnergy?.Shield.ToString();
			var currentArmor = measurement?.Value?.ShipUi?.HitpointsAndEnergy?.Armor.ToString();
			var currentStructure = measurement?.Value?.ShipUi?.HitpointsAndEnergy?.Struct.ToString();
			var currentCapacitor = measurement?.Value?.ShipUi?.HitpointsAndEnergy?.Capacitor.ToString();
			var currentTarID = measurement?.Value.Target?.FirstOrDefault(target => target?.IsSelected ?? false)?.Id.ToString();
			var currentTarShield = measurement?.Value.Target?.FirstOrDefault(target => target?.IsSelected ?? false)?.Hitpoints.Shield.ToString();
			var currentTarArmor = measurement?.Value.Target?.FirstOrDefault(target => target?.IsSelected ?? false)?.Hitpoints.Armor.ToString();
			var currentTarStructure = measurement?.Value.Target?.FirstOrDefault(target => target?.IsSelected ?? false)?.Hitpoints.Struct.ToString();
			var shipAction = "";
			shipAction = measurement?.Value?.ShipUi?.Indication?.LabelText?.FirstOrDefault()?.Text.ToString();
			var arrModules = measurement?.Value?.ShipUi?.Module?.ToArray();
			int timeKeepingInt = Environment.TickCount & Int32.MaxValue;
			string timeKeeping = timeKeepingInt.ToString();
			data["Sanderling"]["timeKeeping"] = timeKeeping;

			// Snip
			var columns = measurement?.Value?.WindowOverview?.FirstOrDefault()?.ListView?.ColumnHeader?.ToArray();
			if (columns != null)
			{
				if (columns.Length > 0)
				{
					int distanceElementNum = 0;
					int typeElementNum = 0;
					// Snip...
					if (arrOverview != null)
					{
						for (int i = 0; i < arrOverview.Length; i++)
						{
							var line = arrOverview[i];

							string lineNum = (i + 1).ToString();
							
							// Snip...
							
							var LineX1 = line?.Region.Min0.ToString();
							var LineY1 = line?.Region.Min1.ToString();
							var LineX2 = line?.Region.Max0.ToString();
							var LineY2 = line?.Region.Max1.ToString();
							var lineID = line?.Id.ToString();
							var iniEntry = "OverviewLine" + lineNum;
							string type = "";
							string Distance = "";
							try
							{
								type = line?.LabelText?.ElementAt(typeElementNum)?.Text;
								Distance = line?.LabelText?.ElementAt(distanceElementNum)?.Text;
							}
							catch
							{
								type = "";
								Distance = "";
							}

							// Snip...
						}
					}
					var ShipSpeed = measurement?.Value?.ShipUi?.SpeedLabel?.Text;
					
					var arrSquadrons = measurement?.Value?.ShipUi?.SquadronsUI?.SetSquadron?.ToArray();
					if (arrSquadrons != null)
					{
						for (int i = 0; i < arrSquadrons.Length; i++)
						{
							var iniSquadEntry = "Squad" + (i + 1).ToString() + "Info";
							var squad = arrSquadrons[i];

							var Squadron1Health = squad?.Squadron?.Hint?.ToString();
							if (Squadron1Health != null)
							{
								Squadron1Health = Squadron1Health.Replace("\r", " ");
								Squadron1Health = Squadron1Health.Replace("\n", " ");
							}
							var Squadron1Selected = squad?.Squadron?.IsSelected?.ToString();
							var Squadron1Status = squad?.Squadron?.LabelText?.ElementAtOrDefault(1)?.Text;
							var Squadron1GunsActive = squad?.SetAbilityIcon?.ElementAtOrDefault(2)?.RampActive?.ToString();
							var Squadron1MWDActive = squad?.SetAbilityIcon?.ElementAtOrDefault(1)?.RampActive?.ToString();
							var Squadron1MissileActive = squad?.SetAbilityIcon?.ElementAtOrDefault(0)?.RampActive?.ToString();
							var Squadron1MissileQuant = squad?.SetAbilityIcon?.FirstOrDefault(ability => ability?.Quantity != null)?.Quantity.ToString();
						}
					}
					
				}
			}
			else
			{
				data["Sanderling"]["ShipStats"] = 100 + "|" + 100 + "|" + 100 + "|" + 100 + "|Docked";
				parser.WriteFile(LocalInipath, data);
			}
			
		}

Updated original post with some of the code I use.

all object, no, just some of them ( i mentioned in some posts)
sometime a blue is red
sometime drones window
or probes window
sometime he didn’t see the wrecks
sometime he didn’t see the modules/or afterburner etc
and sometimes he enter in combat mode even if there is no rats.
but the comp was loaded ( 30-40 windows in browser, 30 pdf, 10 office,2* VS, movies, music +the game +rdp etc)
also the windows had to update

I tested with sanderling ( different versions)
and I tested with abot, different versions /orbit, original, my own.

restarting the bot didnt resolve the issue ( that why i changed all and retested)
restarting the game didnt resolve the issue.
changing the computer yes
so I restarted the computer.

and it was ok

so in my opinion is the bot ( his memory reading) but more is the memory loading /stocking.

Edit later:
since the bot read the memory and you( and/or me ) have a good loading on memory, i believe it’s the windows fault.
Also from a while, the game is changing … from a day to next one, the servers crash, you take disconnect, an object is there but is not visible and so on, today you have a rat full of faction loot and tomorow anything is changed… is not so sure.
My advice is from eve: fly only what you can afford to lose :); don’t bother too much

@Viir is there anything that can be done for this issue? This is kind of a big issue.

i’m certainly sure it is not issue in framework. I don’t have any issues with readings at all.

note: running my own version of sanderling Abot as admin / w10 64bit

I’m running same, on 8 VMs. Are you running enough to have a large chance of it happening? Is there an API function I can do when my code realizes this is happening? A function that finds the memory objects again?

if you send me the script … i could try it out

The script above looks to only do measurements … does your actual script do anything else?

I run on a vm as well … I often wonder if there is a memory leak …

The script only gets measurements and then my AHK scripts use them. On errors it writes all measurements to a log and takes a screenshot. Screenshot shows the overview, but measurements show null for overview. I’ve never used any of the built in Sanderling bots. Is there some API that keeps this from happening or fixes thins like this?

I’m not running them 8th times but I’m running my code long enough to say it’s not fault of the framework at all.

might be issue in your VM, frankly nobody really knows what VM emulates and how

From your post, I understand this issue is specific to a scenario where you use your own code. In such a case, I don’t know what you are doing.

It depends the program code you are using.
What is the smallest change in the source code from the sanderling master branch which causes the issue to appear?

I appreciate any help.
I’m trying to figure out how to save the project so that you can look at it in an IDE, but here’s the best I can do real quick. (Is there more that I can provide to help?)

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Castle.Core" version="3.3.3" targetFramework="net461" />
  <package id="fasterflect" version="2.1.3" targetFramework="net461" />
  <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" />
  <package id="protobuf-net" version="2.1.0" targetFramework="net461" />
</packages>
using Bib3.Geometrik;
using Sanderling.Interface.MemoryStruct;
using BotEngine.Interface;
using System;
using System.Linq;
using System.Threading;
using BotEngine.Common;
using System.Collections; //Required
using System.Collections.Generic;
using System.Text.RegularExpressions;

using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;

namespace Sanderling.Sample.Read
{
	/// <summary>
	/// This is just a minimal example of how to read from the eve online client process' memory.
	/// For more information, visit the project page at https://github.com/Arcitectus/Sanderling
	/// </summary>
	class Program
	{
		const int MeasurementTimeDistance = 300;
		static void SampleRun()
		{
			///Console.WriteLine("this program reads the memory of the eve online client process.");
			var eveOnlineClientProcessId = Extension.GetEveOnlineClientProcessId();

			if (null == eveOnlineClientProcessId)
			{
				Console.WriteLine("reading eve online client process id failed.");
				return;
			}

			///Console.WriteLine("\nstarting to set up the sensor and read from memory.\nthe initial measurement takes longer.");

			var sensor = new Sensor();

			for (; ; )
			{
				var stopwatch = new System.Diagnostics.Stopwatch();
				string totalTime;
				stopwatch.Start();
				var response = sensor?.MeasurementTakeNewRequest(eveOnlineClientProcessId.Value);
				stopwatch.Stop();
				totalTime = stopwatch.ElapsedMilliseconds.ToString();
				Console.Write("Time to take measurement and analysis: " + totalTime + "ms\n");
				if (null == response)
					continue;
				///Console.WriteLine("Sensor Interface not yet ready.");
				else
					MeasurementReceived(response?.MemoryMeasurement);
				Thread.Sleep(MeasurementTimeDistance);
			}
		}

		/// <param name="measurement">contains the structures read from the eve online client process memory.</param>
		static public void MeasurementReceived(BotEngine.Interface.FromProcessMeasurement<IMemoryMeasurement> measurement)
		{
		}
	}
}

Newest commit I see on master branch is Fix Bug · Arcitectus/Sanderling@4cf71f3 · GitHub

If you upload a commit to github with your changes based on that commit I can take a look at it.

I made no changes to the core code. I just used the API. When I next find it happening can I do anything to document it?

When the problem disappears with restarting Sanderling, it is tricky to document. In this case, a snapshot of the eve client process might not be sufficient to reproduce the problem.
You can save the memory measurement to a file which might be helpful for investigation. In the Sanderling app, you do it like described in the guide at How To Save A Memory Measurement To A File, use the MemoryMeasurement path to get the measurement before parsing. When you don’t have the measurement in the Sanderling App, you can use the approach from Parse.MemoryMeasurement serialization across processes to serialize the memory measurement to a string and then save this to a file using UTF8 Encoding.
In any case, record a screenshot of the eve client window along with the memory measurement.

Guys,

I have also noticed this issue but only on my sanderling instance running Windows 10 on a Parallels VM. Sometimes it will take quite a while for sanderling to acquire the first valid VM measurement, then it will work fine for a while, then lose the ability to do memory measurements again. I do not see it on my bare metal window install. Just thought I would share my current experience. Not sure if it is somehow VM related, or perhaps exposed by a slower running instance.

Hack

1 Like

Hmm, you just gave me an idea for what the cause could be… Dynamic or shared memory could be a reason. I’ll try them without it. Thanks!

Edit: still happening with static memory allocation.

I find that windows 10 under VM runs sanderling and eve very slowly with 2GB memory assigned to it … as time passes it gets worse and worse for both …

I have recompiled sanderling so I can run an x86 version with windows 7 x86 version (x86 appears to run without the eventual slowing down of eve and sanderling)

my two cents

@jyhad thank you for this. I have noticed over the last couple month my VM is getting excessively sluggish when I start sanderling to the point where the eve client becomes very unresponsive.

Hack.

Do you see memory usage for the Sanderling process growing in that case?
What is the maximum value you see in the Windows Task Manager under Memory for the Sanderling process?

https://i.imgur.com/iaEBii8.png

My VMs reboot once per day, and I don’t notice enough RAM increase to be worth investigating. (If any, it is under 10% of VM RAM.)