From 522ab179c3e834c71e7b557c099447fc3648e065 Mon Sep 17 00:00:00 2001 From: Markus Klotzbuecher Date: Wed, 15 Jul 2020 11:10:22 +0200 Subject: [PATCH] doc: update and cleanup FAQ Signed-off-by: Markus Klotzbuecher --- docs/user/developing_blocks.rst | 48 +-------- docs/user/faq.rst | 185 +++++++++++++++++++++++++------- 2 files changed, 149 insertions(+), 84 deletions(-) diff --git a/docs/user/developing_blocks.rst b/docs/user/developing_blocks.rst index 96dc75d4..2eb33391 100644 --- a/docs/user/developing_blocks.rst +++ b/docs/user/developing_blocks.rst @@ -593,6 +593,7 @@ Run ``ubx-launch -h`` for full options. Browse to http://localhost:8888 + Block Interface Guidelines -------------------------- @@ -600,47 +601,6 @@ Block Interface Guidelines is sufficently large and errors can be returned as negative values (example: ``cfg_getptr_uint32``). - -Tips and Tricks ---------------- - -Using C++ -~~~~~~~~~ - -See the example ``std_blocks/cppdemo``. - -.. note:: Please note that *designated initializers* used to - initialize ``ubx_proto_`` structures are only supported by - g++ versions 8 and newer! - - -Speeding up port writing -~~~~~~~~~~~~~~~~~~~~~~~~ - -To speed up port writing, the pointers to ports can be cached in the -block info structure. The ``ubx-genblock`` script automatically takes -care of this. - -What the difference between block types and instances? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -There are very few differences. A prototype block is added by module -init functions using ``ubx_block_register`` and must also be removed -by the corresponding module cleanup hook using -``ubx_block_unregister``. A prototype blocks ``prototype`` ptr is -NULL. - -Block instances are cloned from existing blocks using -``ubx_block_create`` and the instances ``block->prototype`` pointer is -set to the block is was cloned from. Normally blocks are cloned from -prototype blocks, but it is possible to clone any block (a warning is -issued currently). - - -Module visibility -~~~~~~~~~~~~~~~~~ - -It is suggested to add ``-fvisibility=hidden`` to CFLAGS. This way, -there’s no need to clutter functions and global variables with -``static``. - +- (i)blocks that allow configuring *type* and *length* of data to be + handled should use the canonical config names ``type_name`` and + ``data_len``. diff --git a/docs/user/faq.rst b/docs/user/faq.rst index 9787a0e4..f6c72ffc 100644 --- a/docs/user/faq.rst +++ b/docs/user/faq.rst @@ -1,47 +1,63 @@ Frequently asked questions ========================== -meta-microblx yocto layer: luajit build fails ---------------------------------------------- +Developing blocks +----------------- -``luajit`` fails with the following message: +How to use C++ for blocks +~~~~~~~~~~~~~~~~~~~~~~~~~ -.. code:: sh - - arm-poky-linux-gnueabi-gcc -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a8 -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=/build/bbblack-zeus/build/tmp/work/cortexa8hf-neon-poky-linux-gnueabi/luajit/2.0.5+gitAUTOINC+02b521981a-r0/recipe-sysroot -fPIC -Wall -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -U_FORTIFY_SOURCE -DLUA_ROOT=\"/usr\" -DLUA_MULTILIB=\"lib\" -fno-stack-protector -O2 -pipe -g -feliminate-unused-debug-types -fmacro-prefix-map=/build/bbblack-zeus/build/tmp/work/cortexa8hf-neon-poky-linux-gnueabi/luajit/2.0.5+gitAUTOINC+02b521981a-r0=/usr/src/debug/luajit/2.0.5+gitAUTOINC+02b521981a-r0 -fdebug-prefix-map=/build/bbblack-zeus/build/tmp/work/cortexa8hf-neon-poky-linux-gnueabi/luajit/2.0.5+gitAUTOINC+02b521981a-r0=/usr/src/debug/luajit/2.0.5+gitAUTOINC+02b521981a-r0 -fdebug-prefix-map=/build/bbblack-zeus/build/tmp/work/cortexa8hf-neon-poky-linux-gnueabi/luajit/2.0.5+gitAUTOINC+02b521981a-r0/recipe-sysroot= -fdebug-prefix-map=/build/bbblack-zeus/build/tmp/work/cortexa8hf-neon-poky-linux-gnueabi/luajit/2.0.5+gitAUTOINC+02b521981a-r0/recipe-sysroot-native= -c -o lj_obj_dyn.o lj_obj.c - In file included from /usr/include/bits/errno.h:26, - from /usr/include/errno.h:28, - from host/buildvm.h:13, - from host/buildvm_fold.c:6: - /usr/include/linux/errno.h:1:10: fatal error: asm/errno.h: No such file or directory - 1 | #include - | ^~~~~~~~~~~~~ - compilation terminated. +Checkout the example ``std_blocks/cppdemo``. -This solution is to install ``gcc-multilib`` on the build host. +.. note:: *designated initializers*, which are used to initialize + ``ubx_proto_`` structures are only supported by g++ versions + 8 and newer! -"undefined symbol" errors when loading modules ----------------------------------------------- +What the difference between block types and instances? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Try rerunning ldconfig (``sudo ldconfig``). It seems there is an -libtool issue https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=684981 -that makes this necessary under certain circumstances (?). +There are very few differences. A prototype block is added by module +init functions using ``ubx_block_register`` and must also be removed +by the corresponding module cleanup hook using +``ubx_block_unregister``. A prototype blocks ``prototype`` ptr is +NULL. +Block instances are cloned from existing blocks using +``ubx_block_create`` and the instances ``block->prototype`` pointer is +set to the block is was cloned from. Normally blocks are cloned from +prototype blocks, but it is possible to clone any block (a warning is +issued currently). -fix “error object is not a string” ----------------------------------- +That said, the above are *internals* and you should not rely on +them. Instead, use the predicates ``blk_is_proto`` and +``blk_is_instance`` if you need to determine what is what. -Note that this has been fixed in commit ``be63f6408bd4d``. +Why do you cache port pointers in the block info structure? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This is most of the time happens when the ``strict`` module being loaded -(also indirectly, e.g. via ubx.lua) in a luablock. It is caused by the C -code looking up a non-existing global hook function. Solution: either -define all hooks or disable the strict module for the luablock. +For two reasons: + +- it's simpler to cache it once and then just use the pointer directly +- to a lesser degree: for performance. It avoids a repeated hash table + lookups in ``step``. +Note that the ``ubx-genblock`` script automatically takes care caching +ports of this. + + +Avoiding ``static`` +~~~~~~~~~~~~~~~~~~~ + +You can avoid cluttering block functions and globals with ``static``, +by adding ``-fvisibility=hidden`` to ``CFLAGS``. + + +Running microblx +---------------- ``blockXY``.so or ``liblfds611.so.0``: cannot open shared object file: No such file or directory ------------------------------------------------------------------------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ There seems to be a `bug `_ in some @@ -50,7 +66,7 @@ can manually fix this by running .. code:: sh - $ sudo ldconfig + $ sudo ldconfig Often this means that the location of the shared object file is not in @@ -64,8 +80,21 @@ try adding it to ``LD_LIBRARY_PATH``, e.g. It would be better to install stuff in a standard location such as ``/usr/local/``. -Real-time priorities --------------------- + +luablock: “error object is not a string” +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Note that this has been fixed in commit ``be63f6408bd4d``. + +This is most of the time happens when the ``strict`` module being loaded +(also indirectly, e.g. via ubx.lua) in a luablock. It is caused by the C +code looking up a non-existing global hook function. Solution: either +define all hooks or disable the strict module for the luablock. + + + +Running with real-time priorities +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To run with realtime priorities, give the luajit binary ``cap_sys_nice`` capabilities, e.g: @@ -75,26 +104,42 @@ capabilities, e.g: $ sudo setcap cap_sys_nice+ep `which luajit` Note that this will grant these capabilities to luajit binary in -`PATH`. If you don't want to do this system-wide, then specify a -different version! +`PATH`. If you don't want to do this system-wide, you can do this for +a local ``luajit`` binary instead. + +In addition, you should pass the command-line option ``-mlockall`` to +``ubx-launch``, to ensure memory is locked. For scripts, pass the +``ND_MLOCK_ALL`` node attribute to ``ubx_node_init``. + +I'm not getting core dumps when running with real-time priorities +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is not a bug, but a safety mechanism to prevent potential leaking +of priviledged data from a ``setcap`` process. To override this, pass +the ``ubx-launch`` command-line arg ``-dumpable`` or the for scripts +the node attribute ``ND_DUMPABLE``. + My script immedately crashes/finishes -------------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This can have several reasons: -- You forgot the ``-i`` option to ``luajit``: in that case the script - is executed and once completed will immedately exit. The system will - be shut down / cleaned up rather rougly. +- You forgot the ``-i`` option to ``luajit``: in that case the script + is executed and once completed will immedately exit. The system will + be shut down / cleaned up immediately. -- You ran the wrong Lua executable (e.g. a standard Lua instead of - ``luajit``). +- You ran the wrong Lua executable (e.g. a standard Lua instead of + ``luajit``). If none of this works, see the following topic. +Debugging +--------- + Debugging segfaults -------------------- +~~~~~~~~~~~~~~~~~~~ One of the best ways to debug crashes is using gdb and the core dump file: @@ -131,3 +176,63 @@ example with gdb attached: prefixes: /usr, /usr/local [New Thread 0x7ffff7871700 (LWP 2831757)] ... + + +Running valgrind +~~~~~~~~~~~~~~~~ + +Valgrind is very useful to track down memory leaks or sporadic +segfaults. To run it on dynamically loaded modules, the +``UBX_CONFIG_VALGRIND`` flag must be enabled in ``ubx.h``. This flag +will pass the ``RTLD_NODELETE`` flag to ``dlopen(3)``, which causes +modules not really to be unloaded. This is essential for valgrind to +print meaningful traces in module code. + +After that, you can run valgrind as follows on an `usc` file: + +.. code:: sh + + valgrind --leak-check=full \ + --track-origins=yes \ + luajit `which ubx-launch` -t 3 -c examples/usc/threshold.usc + ... + + +This will run the demo for 3 seconds and then exit. Valgrind may print +warnings related to luajit like ``Conditional jump or move depends on +uninitialised value``, which can be ignored (or silenced by building +luajit with valgrind support , see ``-DLUAJIT_USE_VALGRIND``) + +Running a script can be done likewise: + +.. code:: sh + + $ valgrind --leak-check=full \ + --track-origins=yes \ + luajit tests/test_ptrig.lua + ... + + +meta-microblx +------------- + +building luajit fails +~~~~~~~~~~~~~~~~~~~~~ + +``luajit`` fails with the following message: + +.. code:: sh + + arm-poky-linux-gnueabi-gcc -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a8 -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=/build/bbblack-zeus/build/tmp/work/cortexa8hf-neon-poky-linux-gnueabi/luajit/2.0.5+gitAUTOINC+02b521981a-r0/recipe-sysroot -fPIC -Wall -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -U_FORTIFY_SOURCE -DLUA_ROOT=\"/usr\" -DLUA_MULTILIB=\"lib\" -fno-stack-protector -O2 -pipe -g -feliminate-unused-debug-types -fmacro-prefix-map=/build/bbblack-zeus/build/tmp/work/cortexa8hf-neon-poky-linux-gnueabi/luajit/2.0.5+gitAUTOINC+02b521981a-r0=/usr/src/debug/luajit/2.0.5+gitAUTOINC+02b521981a-r0 -fdebug-prefix-map=/build/bbblack-zeus/build/tmp/work/cortexa8hf-neon-poky-linux-gnueabi/luajit/2.0.5+gitAUTOINC+02b521981a-r0=/usr/src/debug/luajit/2.0.5+gitAUTOINC+02b521981a-r0 -fdebug-prefix-map=/build/bbblack-zeus/build/tmp/work/cortexa8hf-neon-poky-linux-gnueabi/luajit/2.0.5+gitAUTOINC+02b521981a-r0/recipe-sysroot= -fdebug-prefix-map=/build/bbblack-zeus/build/tmp/work/cortexa8hf-neon-poky-linux-gnueabi/luajit/2.0.5+gitAUTOINC+02b521981a-r0/recipe-sysroot-native= -c -o lj_obj_dyn.o lj_obj.c + In file included from /usr/include/bits/errno.h:26, + from /usr/include/errno.h:28, + from host/buildvm.h:13, + from host/buildvm_fold.c:6: + /usr/include/linux/errno.h:1:10: fatal error: asm/errno.h: No such file or directory + 1 | #include + | ^~~~~~~~~~~~~ + compilation terminated. + +This solution is to install ``gcc-multilib`` on the build host. + +