NULL deref when using JPL ephemeris
Closed this issue · 6 comments
Hi,
I recently started using SwissEph. I love that it is so powerful. But using JPL ephemeris, I am getting a null deref exception:
public int swi_pleph(double et, int ntarg, int ncent, CPointer<double> rrd, ref string serr) {
int i, retc;
Int32[] list = new Int32[12];
double[] pv = js.pv; <<<<<< js is null.
I solved the problem by commenting out
js = null
in swi_close_jpl_file(); Obviously this is hacky, and I am curious about what the root cause is. What is the real fix here?
Here is my test app:
using SwissEphNet;
using System;
using System.Text.RegularExpressions;
namespace SweMini
{
class Program
{
static int Main(string[] args)
{
string sdate = String.Empty, serr = String.Empty;
int jday = 1, jmon = 1, jyear = 2000;
double jut = 0.0;
using (var swe = new SwissEph())
{
swe.swe_set_ephe_path(@"X:\Projects\Swiss\jplfiles");
swe.swe_set_jpl_file("de430.eph");
swe.OnLoadFile += swe_OnLoadFile;
while (true)
{
Console.Write("\nDate (d.m.y) ? ");
sdate = Console.ReadLine();
if (String.IsNullOrWhiteSpace(sdate))
break;
/*
* stop if a period . is entered
*/
if (sdate == ".")
return SwissEph.OK;
var match = Regex.Match(sdate, @"(\d+)\.(\d+)\.(\d+)");
if (!match.Success)
continue;
jday = int.Parse(match.Groups[1].Value);
jmon = int.Parse(match.Groups[2].Value);
jyear = int.Parse(match.Groups[3].Value);
/*
* we have day, month and year and convert to Julian day number
*/
var jd = swe.swe_julday(jyear, jmon, jday, jut, SwissEph.SE_GREG_CAL);
double[] pos = new double[] { 0, 48, 0 };
double risetime = 0;
swe.swe_rise_trans(
jd,
SwissEph.SE_MOON,
null,
SwissEph.SEFLG_JPLEPH,
SwissEph.SE_CALC_SET,
pos,
1013.25,
20,
ref risetime,
ref serr);
int year = 0, month = 0, day = 0, hour = 0, minute = 0;
double second = 0;
swe.swe_jdet_to_utc(risetime, SwissEph.SE_GREG_CAL,
ref year, ref month, ref day, ref hour, ref minute, ref second);
Console.WriteLine($"{year}/{month}/{day} {hour}:{minute}:{second}");
}
}
return 0;
}
static void swe_OnLoadFile(object sender, LoadFileEventArgs e)
{
var f = e.FileName;
if (System.IO.File.Exists(f))
e.File = new System.IO.FileStream(f, System.IO.FileMode.Open, System.IO.FileAccess.Read);
}
public static void printf(string Format, params object[] Parameters)
{
Console.Write(C.sprintf(Format, Parameters));
}
}
}
Hi,
Thanks for the report.
I'll try to look it quickly (this WE if I can).
I'll try to reproduce your issue on .Net and on in original DLL Swiss Ephemeris to see if this error is raised on the original code too.
You are awesome, thanks a lot! I look forward to your findings. Good luck :)
BTW, I am not sure if this is related, but there seems to be other problems when using JPL ephemerides. For example:
swe.swe_sol_eclipse_when_glob(jd, SwissEph.SEFLG_JPLEPH, SwissEph.SE_ECL_TOTAL, tret, false, ref serr);
fails with
"jd 2689359.814575 outside JPL eph. range 2287184.50 .. 2688976.50; \nusing Moshier Eph; "
but
swe.swe_sol_eclipse_when_glob(jd, SwissEph.SEFLG_SWIEPH, SwissEph.SE_ECL_TOTAL, tret, false, ref serr);
works beautifully. My input JD is 2457754.5 (i.e. 1.1.2017)
OK I confirm it's a bug of the SwissEph.Net only.
Apparently the opened file is closed BEFORE used by the calculation. I didn't find where, but now I have some ways to find the bug.
I'll continue my search soon.
OK the version 2.6.0.22 fix the bug.
One thing: in your code, set the OnLoadFile
event BEFORE using the swe_set_ephe_path()
and swe.swe_set_jpl_file()
methods because there load file, so in your sample your must be
using (var swe = new SwissEph())
{
swe.OnLoadFile += swe_OnLoadFile;
swe.swe_set_ephe_path(@"X:\Projects\Swiss\jplfiles");
swe.swe_set_jpl_file("de430.eph");
...
}
regards,
Again, you are awesome. I can confirm that this issue is fixed.
Regarding the OnLoadFile. Yes, of course, it should be before setting path etc. What was I thinking! :)