Symbol lookup best practices?

Most of the time the simulator starts without a problem, but sometimes I get this when I start:

Error: Invalid Value

Details: Failed invoking <symbol>
Stack:
- onUpdate() at C:\Users\Andy\Desktop\Garmin-GIT\Annulus\source\AnnulusView.mc:735 0x10002514

Encountered app crash.
Kill app for run the app
Failed to run the app: Timeout

What's worse it's happening on the watch, after a day or so onUpdate will stop updating when awake, but it does keep updating every minute awake or not. I get something similar in a CIQ_LOG file. I reselect the watch face and it's fine, at least for a while.

Can I fix this by helping the lookup process? I don't have any globals beyond Toybox, so do I use self to say it's a variable or function in the same class? Does a symbol need to be looked up everytime that piece of code is run, or does it remember after the first time? It seems like if it was remembering where it was it wouldn't break the next day.

  • Does you app also run in the background? When the background process starts it also calls the constructor of the app.

    I don't understand why did you post the above 15 lines. What do we see here? Which one of them is 0? Where it is used 700 later?...

    I hate to write this again, but as much as we're trying to help, we don't read your mind, we can only use the information you give us.

  • Good question. They're J2000.0 dates. Maybe my optimization efforts are paying off and some things are now taking less than a second so now uptime looks like zero.

  • No, nothing in the background. What I posted was to show that the initialize part is what seems to be to be fairly standard, nothing but the boilerplate stuff from Garmin and setting some variables to zero so they won't be null later.

    in initialize()

    _jAwake = 0;

    jparts = Astro.j2kNow();
    _jStart = jparts[0] - 1e-6d;  // I've since added this bias

    Then:

    public function onUpdate(dc as Dc) as Void {
    self.jparts = Astro.j2kNow();
    var jday = self.jparts[0];

    // debug awake time
    self._jAwake++;
    var upTime = jday - self._jStart;
    var awakeDay = self._jAwake / upTime;

    _jAwake is a Number, upTime is a Double. I'm only seeing this recently because I've only recently started tracking awake time to see where my battery usage was going. I might have to add milliseconds from getTimer() if I'm going to keep using it for this but it would be more useful if I knew the boot time.

  • I think you should not hack your own code but rather fix the real problem: instead of adding a very small floating point number to make something non-zero (that because of how floating points works maybe not changing the value at all?)

    why not:
    var awakTime = upTime == 0.0d ? something :self._jAwake / upTime;

  • What I need it for doesn't need to be that precise. I'm just trying to get an idea of awake time per day and how it impacts battery life for my app. That little bit to keep it from being zero is below the noise level.

  • Not seeing the obvious (even when someone is pointing to it) is a serious problem, but if you prefer you can try to continue to debug why you are dividing by zero in line 710 and try to hack it in line 10 instead of do the right think in line 710

  • I've been programming for 40+ years, long enough to know why I always started all my Fortran programs with IMPLICIT NONE. I know how computer math does and doesn't work. I'm no longer concerned about the div by zero problem, I've solved it as far as I need it to be. Yes I know your solution is pretty and mine is a kludge, but at some point soon that code will get deleted so there isn't any requirement to be pretty. If I really wanted to solve it right I would use System.getTimer() since it's either the system uptimer or the next best thing, but it's apparently an unsigned int internally but exposed as signed based on how they described it working. My bigger concern is why the application is apparently randomly restarting. I've added some more tracing statements, if there is something else anyone thinks might be helpful for tracing and debugging that problem I'm all ears.

  • When you move to the widget/lance loop and come back, your app will restart on most devices.  Same if you go to controls or activities

  • Is something running at night, like some garbage collector?

  • BTW, the code to avoid by zero is pretty minor and  just 1 line of code.  When I started with Fortran, it would be easy to type using a keypunch machine!  Slight smile

    result=(myDivisor==0) ? myValue : myValue/myDivisor;