Search code examples
c++node.jsdebuggingnode-gyp

Debugging nodejs nbind c++ addons


I'm currently trying to write a C++ NodeJS plugin using nbind with the universal example. Building and running the example works perfectly. Now I have two questions, first related to general debugging, the second related to my problem.

I added the RF24 lib. Constructing an RF24 object also works, but calling for example getChannel() or printDetails() function in Nodejs returns just

terminated called after throwing an instance of 'int'
npm ERR! Test failed. See above for more details

How am I able to get more details out of the errors, e.g. file and line number? I tried adding node-gyp configure --debug build --debug flags, but the build also only produces a Release folder.

My building command is the following, like suggested in the universal example.

"build:native": "autogypi -r build && node-gyp -C build/native configure --debug build --debug && copyasm build/native dist"

I'm building on RPi Zero W (Arm v6). My current binding.gyp located in ./build/native looks as follows

{
  "targets": [
    {
      "includes": [ "../auto.gypi" ],
      "sources": [
        "../../src/example.cpp",
        "../../libs/RF24-master/RF24.cpp",
        "../../libs/RF24-master/utility/RPi/bcm2835.cpp",
        "../../libs/RF24-master/utility/RPi/interrupt.cpp",
        "../../libs/RF24-master/utility/RPi/spi.cpp"
      ],
      "include_dirs": [
        "../../src",
        "../../libs/RF24-master"
      ],
      "cflags": [
        "-std=c++11",
        "-fpermissive"
      ],
      "cflags_cc!": [ "-fno-rtti" ] 
    }
  ],
  "includes": [
    "../auto-top.gypi"
  ]
}

The simplified program example.cpp looks like

#include "RF24.h"
#include "example.h"

Example::Example(uint16_t cePin, uint16_t spiBus): cePin(cePin), spiBus(spiBus) {
  this->radio = new RF24(cePin, spiBus);
}

uint8_t Example::getChannel() {
  return this->radio->getChannel();
}

And the corresponding header example.h looks like

#ifndef EXAMPLE_H
#define EXAMPLE_H

class Example{
  uint8_t cePin = 22, spiBus = 0;
  RF24* radio;

  public:
    Example(uint16_t cePin, uint16_t spiBus);
    uint8_t getChannel();
};

#endif

#include "nbind/nbind.h"

NBIND_CLASS(Example) {
  construct<uint8_t, uint8_t>();
  method(getChannel);
}

So there are two questions

  • General and more important: How do I get more comfortable debugging options for nbind c++ addons?
  • More specific to my problem and related to RF24: Why does that error appear at each RF24 function call?

Solution

  • For the first question I got a solution. NodeJS runs well with gdb. So doing

    sudo gdb node
      > run myscript.js
    

    prints the following a little more detailed error

    Thread 1 "node" received signal SIGSEGV, Segmentation fault.
    0xb4c15ff8 in bcm2835_peri_read () from /usr/local/lib/librf24.so.1
    

    If someone's around knowing what's going on or ideas on how to dig further, you're welcome. I used the RF24 script to make a shared library instead of building it with node-gyp. The error it produces is exactly the same.

    EDIT: I build a workaround for testing purposes without nodejs first. It's working when giving the program root permissions. As it is a standalone rasbpi not connected to any network, root wouldn't be a problem. The nodejs addon requires root permissions because of SPI and GPIO.