Avatar for !evil


Member since Dec 2022 • Last active Feb 2023
  • 7 conversations

Most recent activity

  • in General
    Avatar for !evil

    Espruino should continue working just fine after an out of memory
    error - and actually the Linux build does have a 'memtest' where it'll
    just run the tests time after time, slowly decreasing memory so that
    it can see if anything breaks badly when out of memory happens at
    different times.

    This is very reassuring :) Thanks for the guidance!

  • in General
    Avatar for !evil

    Sorry for the confusion, i meant "out of memory", not out of array bounds. I hope the following is better.

    In _jswrap_interface_setTimeoutOrInterval, timerPtr is zero if there isn't enough memory. This might not have immediate consequences if all future ops align well (like jsvObjectSetChildAndUnLock). Or itemIndex may be zero despite a new timer. The consequences in this particular case may be negligible, so it may be just a bad example.

    Regarding jsvObjectSetChildAndUnLock: if jsvObjectSetChildVar returns zero due to "out of memory", it won't unlock child (https://github.com/espruino/Espruino/blo­b/7277a8dc9377e09f9a6837ff754e3dd8dd7615­63/src/jsvar.c#L3005). Compare with jsvArrayPushAndUnLock where value is unlocked regardless (https://github.com/espruino/Espruino/blo­b/7277a8dc9377e09f9a6837ff754e3dd8dd7615­63/src/jsvar.c#L3298).

    The main question is: care about "out of memory" (e.g. if (var) { ...; jsvUnLock(var); } all the way) because there is a sane future for the system after the incident, or don't and assume nothing bad will happen. Both viable imo.

  • in Bangle.js
    Avatar for !evil

    With bluetoothctls shell you can execute remove {MAC} as well as scan le, devices, scan off. And as a last resort power off and power on. It does remember previous commands but won't autocomplete afaik. I assume there are cmdline arguments for scripting.

  • in General
    Avatar for !evil


    I was wondering what the recommended approach to memory overflow is. Most of jsvar.c check for overflow and behave accordingly, while other code assume no overflow, e.g. _jswrap_interface_setTimeoutOrInterval. Then there is jsvObjectSetChildAndUnLock which doesn't unlock the child in case of overflow, while others like jsvArrayPushAndUnLock do.

    I tried to use the following defines for perfect overflow coverage in my library

    ﹟define INIT(n) JsVar* _lock_array[n]; int _lock_index = 0
    ﹟define END(i) _end(i, _lock_array, _lock_index)
    ﹟define NEW(a) ({ JsVar* var = a; if (!var) return END(0); _lock_array[_lock_index++] = var; var; })
    ﹟define TMP(a) ({ JsVar* var = a; if (!var) return END(0); var; })
    ﹟define GRD(a) if (!(a)) return END(0);
    JsVar* _end(int end_index, JsVar** array, int index) {
      while (index != end_index) jsvUnLock(array[--index]);
      return 0;

    but I'm uncertain if its worth the trouble. What if I won't check for overflow, like _jswrap_interface_setTimeoutOrInterval, would it lead to unexpected behavior in case of overflow instead of noisy "segfault"?

  • in Bangle.js
    Avatar for !evil

    I found the issue, and its not Espruino/Bangle. The callback isn't called twice (should have count it earlier) but the returned message on Nordic UART is processed twice on the remote side (Arch Linux, Intel 7260, Bluez 5.66). But only if I didn't remove the device using bluetoothctl after a reset.

    Sorry for the distraction!

    For future reference: when the custom characteristic is added, and my Bluez already knows about the Nordic UART from previous discover, it would immediately disconnect after connect. So I'm forced to remove and rediscover. If, however, it knows about the custom characteristic and the custom characteristic is added during a reset, it wouldn't disconnect after connect but process incoming messages twice. Or at least thats what I see and I'm able to reproduce. Remove and rediscover solves the issue for me.

  • in Bangle.js
    Avatar for !evil


    there is NRF.setServices and I have no trouble setting up a custom service and characteristics when executing code in the IDE, and use it thereafter. Then I tried to put this in a .boot.js file and an issue pops up: the writable characteristic calls onWrite twice each time a message arrives.

    So I thought its because setServices is called multiple times (e.g. after long-press BTN3), but even the following doesn't solve it:

    setTimeout(() => {
      var cc = require('concom');
      cc.t = (0|cc.t) + 1;
      function has_service(sid, cid) {
        var svc = {};
        svc[cid] = {};
        var svcs = {};
        svcs[sid] = svc;
        try {
        } catch (e) {
          return false;
        return true;
      if (has_service(0xf011, 0xf012)) return;
        0xf011: {
          0xf012: {
            maxLen: 53,
            writable: true,
            onWrite: (e) => cc.read(new Uint8Array(e.data))
          0xf013: {
            maxLen: 53,
            notify: true
    }, 3 * 1000);

    When I run its parts individually, everything works (e.g. first has_service returns false, then setServices, then has_service returns true) and I get one onWrite per message. When I do a hard reset with this in the boot file and write to the characteristic, onWrite gets called twice.

    It would be great if anyone could shed some light on this :)

    edit: .t is 1

  • in Bangle.js
    Avatar for !evil

    You are right, and I was wrong. When I removed volatile in the actual application, the issue was still there. After that, initializing with 1 did fix it in the example as well as in the application (... I hope). Thanks a lot!!

    Probably worth to mention somewhere xd