Troubleshooting¶
See also
- Support
- If this page doesn’t help
Reporting Bugs¶
Problem (applies to all implementations)
I’m pretty sure I have found a bug in RSB. What can I do about it?
Solution
First of all, it is entirely possible that you found a bug. We appreciate bug reports and encourage you to report all (suspected) bugs you see, even if you are not entirely certain. Bug reports about things that turn out to not actually be bugs are expected and not a problem. However, to save yourself and us time and effort, we ask you to keep the following things in mind when reporting bugs.
Check whether the problem is known: go to new issue and try to find a description of the problem in the “Issues” list. If there is none, create a new issue (see below), otherwise edit and extend the existing issue as necessary.
Include the following information in your bug report:
Platform
Mainly operating system and processor architecture. For example, “Ubuntu Precise on x86_64” is a very helpful description.Programs and Programming Languages
In which programming language did you write the failing program? If multiple programs are expected to communicate, briefly describe the whole setup.RSB Version
Describe which RSB version you are using and how you obtained it (e.g. installed Debian packages, compiled from source, etc.).What did you do?
Describe what your code does (and include the code, if possible) and/or which programs you started. If you use a RSB configuration file or environment variables, please describe those as well.What did you expect to happen?
What happened instead?
Creating the Report as a new issue:
- In the “Subject” field, try do give a brief description of the specific problem. That is, if you can, write “In C++, informer crashes when trying to send std::string data” instead of “RSB crashes”.
- Put the information mentioned above into the “Description” field and select the value of the “Category” field according to the program and/or programming language.
- Please try to report bugs in the correct project. We understand that this may be hard to figure out and a bug report in the “wrong” project is definitely better than no bug report at all.
Configuration Problems¶
Problem (applies to all implementations)
My RSB program seems to be configured incorrectly, but I cannot tell whether that’s actually the case and if so, why.
Solution
Use the configuration debugging tools provided by RSB.
Spread Does not Work¶
Problem (applies to C++, Python)
Solution
Spread plugin (applies to C++)
See also
- Plugins
Specification of RSB plugins
Starting with version 0.9, the C++ implementation does no longer include the Spread-based transport in the RSB core. Instead, the transport is available as a plugin which has to be loaded explicitly. This can, for example, be done by including the following fragment in one of the RSB configuration files
PREFIX/etc/rsb.conf
,~/.config/rsb.conf
or$(pwd)/rsb.conf
:[plugins.cpp] load = rsbspreadStarting with version 0.7, RSB uses a transport that implements a custom TCP-based protocol to facilitate the easy use of the framework without dependencies on 3rd party libraries. In order to restore the previous behavior of using the Spread transport, the configuration needs to be changed.
This can be changed in three ways:
Globally for all RSB programs (or running under a particular UNIX user)
Create or modify a RSB configuration file
PREFIX/etc/rsb.conf
or~/.config/rsb.conf
to contain the following lines:
1 2 3 4 [transport.spread] enabled = 1 [transport.socket] enabled = 0Lines 3 and 4 can be omitted to enable both transports in parallel.
Locally for the current directory
Create a RSB configuration file
$(pwd)/rsb.conf
with the same contents as described above.For the current shell
Set and export
RSB_TRANSPORT_SPREAD_ENABLED
andRSB_TRANSPORT_SOCKET_ENABLED
environment variables as follows:$ export RSB_TRANSPORT_SPREAD_ENABLED=1 $ export RSB_TRANSPORT_SOCKET_ENABLED=0
Configuring the TCP-based Transport¶
Problem (applies to C++,Common Lisp,Python)
Solution
The TCP-based transport can be configured locally or globally by placing the following content in
PREFIX/etc/rsb.conf
,~/.config/rsb.conf
or$(pwd)/rsb.conf
:[transport.socket] enabled = 1 host = HOSTNAME port = 4444 server = auto
HOSTNAME
can belocalhost
(if all processes are going to run on the same node), a hostname or an IP address.Note
The above configuration uses
server = auto
which causes the initial RSB process to create the specified server and subsequent processes to connect to that server, seeRSB_TRANSPORT_SOCKET_SERVER
.
Linker Errors at Runtime¶
Problem (applies to C++)
I compiled and installed successfully, but RSB binaries/libraries produce linker errors at runtime.
Solution
The C++ implementation of RSB is built without fixed rpath by default. As a result, installed RSB binaries and libraries do not contain information regarding the location of their dependencies. This potentially causes runtime linking to fail because the dependencies cannot be located.
There are two possible solutions:
Building and installing RSB with fixed rpath
This can be achieved by configuring RSB with
$ cmake -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=TRUE
This instructs CMake to set the rpath of installed libraries and executables to the values used for building them. Normally the rpath is stripped at installation time.
Use of the
LD_LIBRARY_PATH
environment variableWhen the value of
LD_LIBRARY_PATH
contains the directory/directories into which RSB (and its dependencies) have been installed, these dependencies can be located at runtime.LD_LIBRARY_PATH
can be set, for example, like this:$ export LD_LIBRARY_PATH=PREFIX/libwhere
PREFIX
is the prefix directory into which RSB and its dependencies have been installed.Warning
This workaround is not permanent and has to be repeated for each new shell that should be able to execute RSB binaries or RSB-based programs.
Spread Warning in Tools¶
Problem (applies to Common Lisp)
When I start any of the Tools, the following happens:
$ logger socket://localhost:7777 WARNING: Failed to load Spread library: Unable to load any of the alternatives: ("libspread-without-signal-blocking.so" "libspread.so" "libspread.so.2" "libspread.so.2.0" "libspread.so.1"). Did you set LD_LIBRARY_PATH? Spread transport will now be disabled. [execution continues, but Spread transport does not work]
Solution
Place one of the mentioned Spread libraries (typicallylibspread.so.2.0
) on the system library search path or setLD_LIBRARY_PATH
appropriately.
Missing Converters¶
See also
- Registering Converters
- Registering additional converters
Problem (applies to all implementations)
When a listener in my component receives certain events, it crashes and complains about missing converters. For example like this:
$ ./myconponent [...] terminate called after throwing an instance of 'rsc::runtime::NoSuchObject
' what(): No converter for wire-schema or data-type `.rst.vision.Image'. Available converters: { bool: *rsb::converter::BoolConverter[wireType = std::string, wireSchema = bool, dataType = bool] at 0x9d0b80 [...] }
Solution
There can be several solutions to this problem.
- The listener could receive unexpected events. This can be diagnosed using the logger. If the listener does indeed receive unexpected events, the problem can be fixed by letting the offending informer or the listener itself operate on a different scope.
- The converter configuration could be wrong. If the listener only receives expected events, it may be missing a suitable converter. This problem can be solved by registering a suitable converter. Registering a converter may be achieved by loading a plugin.
- The converter registration could happen after the listener has already been created. In that case, the listener would use the “old” set of converters.
Polymorphic Informers¶
Problem (applies to C++)
I thought it is possible, to send different data types through the same informer. However, I get this error (also using
rsb::InformerBase
)
Solution
Compilation Errors in Combination with Qt¶
Problem (applies to C++)
Client code using RSB in combination with Qt does not compile correctly. It seems that random errors appear in system header comparable to the following compiler output:
In file included from /usr/include/boost/signals/connection.hpp:13:0, from /usr/include/boost/signals/signal_template.hpp:18, from /usr/include/boost/signals/signal0.hpp:24, from /usr/include/boost/signal.hpp:19, from /vol/csra/releases/nightly/share/rsb0.11/../../include/rsb0.11/rsb/Factory.h:34, from /vol/csra/jenkins/jobs/humavips-headtracking-trunk-toolkit-nightly/workspace/label/master/cxx/image_processing/image_processing/ip_RsbImageProvider.h:40, from /vol/csra/jenkins/jobs/humavips-headtracking-trunk-toolkit-nightly/workspace/label/master/cxx/image_processing/src/ip_DisparityImageProcessor.cc:32: /usr/include/boost/signals/detail/signals_common.hpp:26:13: error: expected identifier before ‘protected’ /usr/include/boost/signals/detail/signals_common.hpp:26:13: error: expected unqualified-id before ‘protected’ In file included from /usr/include/boost/units/detail/utility.hpp:20:0, from /usr/include/boost/exception/detail/type_info.hpp:19, from /usr/include/boost/exception/detail/object_hex_dump.hpp:15, from /usr/include/boost/exception/to_string_stub.hpp:16, from /usr/include/boost/exception/info.hpp:16, from /usr/include/boost/exception/detail/exception_ptr.hpp:20, from /usr/include/boost/exception_ptr.hpp:9, from /usr/include/boost/thread/future.hpp:14, from /usr/include/boost/thread.hpp:24, from /vol/csra/releases/nightly/share/rsc0.11/../../include/rsc0.11/rsc/patterns/Singleton.h:31, from /vol/csra/releases/nightly/share/rsb0.11/../../include/rsb0.11/rsb/Factory.h:41, from /vol/csra/jenkins/jobs/humavips-headtracking-trunk-toolkit-nightly/workspace/label/master/cxx/image_processing/image_processing/ip_RsbImageProvider.h:40, from /vol/csra/jenkins/jobs/humavips-headtracking-trunk-toolkit-nightly/workspace/label/master/cxx/image_processing/src/ip_DisparityImageProcessor.cc:32: /usr/include/c++/4.6/cxxabi.h:47:37: error: expected ‘}’ before end of line /usr/include/c++/4.6/cxxabi.h:47:37: error: expected declaration before end of line
Solution
This compilation error is caused by the fact that RSB uses Boost.Signals which is known to conflict with Qt’s signal mechanism in certain configurations (an explanation is given here). In order to resolve this issue, two solutions exist:
- Reorder includes so that RSB headers always appear before Qt headers. This might sometimes work, but is hard to achieve in other projects.
- Compile your program with
-DQT_NO_KEYWORDS
. This prevents that Qt definessignals
andslots
as preprocessor macros, which is the cause for the compilation error. Your Qt headers that define signals have to useQ_SIGNALS
andQ_SLOTS
instead now.
Multiple Arguments in RPC Calls¶
See also
- Remote Procedure Calls
- Examples about using remote procedure calls
- Request-Reply Communication
- Specification of remote procedure calls
Problem (applies to all implementations)
I would like to call an RPC method with two payloads. RSB seems to only support a single argument in RPC calls, so what is the most elegant way to do this?
Solution
Currently, RSB only supports a single payload for each event. Since RPC calls are implemented in terms of events, the same limitation applies. As a consequence, multiple arguments for a method call have to be collected into a single payload.
Assuming Google Protocol Buffers are used and the method in question should have the signature
add(ComplexNumber, ComplexNumber)
, a definition like the following could be used:message AdditionRequest { required ComplexNumber x = 1; required ComplexNumber y = 2; }For Python, the code implementing this method would then be
def add(request): result = ComplexNumber() result.real = request.x.real + request.y.real result.imag = request.x.imag + request.y.imag return result server.addMethod('add', add)
A Message about no Handlers being found appears¶
Problem (applies to Python)
When I import the
rst
orrstsandbox
module, a message like:No handlers could be found for logger "rstsandbox"appears. Am I doing something wrong?
Solution
Everything is fine. The output is produced by Python’s
logging
module when logging has not been configured. RSB uses this module to log messages.If you find these messages annoying, add the following code fragment to your program:
import logging logging.basicConfig(level = logging.WARNING)See
logging.basicConfig()
for more configuration options.
Java Programs using the Socket Transport do not communicate with other Languages¶
Problem (applies to Java)
Solution
The Java runtime sometime prefers bind sockets to IPv6 addresses even if IPv4 addresses are specified. This seems to be an internal behavior of the Java runtime. Other RSB implementations use IPv4 addresses by default. As a consequence, Java operates on IPv6 and the other languages on IPv4 and connections cannot be established. To force Java to use IPv4, specify the following JVM property (e.g. on the commandline) for RSB Java programs:
-Djava.net.preferIPv4Stack=true
I cannot make the Socket Transport with “auto” Mode work across multiple Machines¶
Problem (applies to all implementations)
I want to connect processes on two or more machines and use the “auto” mode of the socket transport with a configuration like this:
[transport.socket] hostname = SOMEHOST server = autowhere
SOMEHOST
is the name of one of the hosts orlocalhost
. If I start my processes in a particular order, communication sometimes works, but generally I only get failed connection attempts.
Solution
The “auto” mode of the socket transport is intended to be used with simple setups confined to a single computer. It can be used to make such setups “just work”. For other setups, it is only usable with severe restrictions and should probably be avoided.
If you want to connect processes across multiple machines:
Consider switching to the Spread transport if you want to connect very many processes or restart all processes arbitrarily.
If you want to use the socket transport
Determine one particular process that should always act as the server. This can also be an additional process like the Logger or the Server. Note that this choice can impact the performance of your setup very much.
- Configure this (and only this) process to act as server (for example using the environment variable
RSB_TRANSPORT_SOCKET_SERVER
).- Leave this process running all the time.
Configure all other processes to act as clients, for example with this configuration snippet
[transport.socket] hostname = THE-SERVER-HOST server = 0You can add client processes or restart them arbitrarily and also share the above configuration among all client processes.
How many Spread Daemons do I need?¶
Problem (applies to all implementations)
I want to have multiple processes communicate using the Spread transport. Do I need this Spread daemon and if so, how many instances do I have to start and on which machines? I heard that running multiple Spread daemons can even cause severe network problems.
Solution
First of all, Spread daemons really can cause severe network problems when configured incorrectly. We therefore recommend to always start with a single Spread daemon using the default configuration unless a different setup is absolutely necessary. Beyond this simple advice, unfortunately, there are several different possibilities for setting up one or more Spread daemons. In any case, you always need at least one Spread daemon.
If all processes run on a single machine, you can start a single Spread daemon using the default configuration like this:
$SPREAD_INSTALL_PREFIX/sbin/spread
-n localhostThis is a simple and safe configuration and should already cover many simple setups.
If multiple computers are involved, a single Spread daemon with the above configuration may still be sufficient since it can be contacted by clients on remote hosts (see
RSB_TRANSPORT_SPREAD_HOST
). However, this configuration may not achieve the best performance the Spread framework is capable of. If you need better performance and thus more sophisticated configurations, consult the Spread documentation or write to the RSB mailing list.
Participants (or something else) are not cleaned up¶
Problem (applies to all implementations)
I have the impression that RSB does not properly clean up all participants (or maybe some other objects) when my program terminates or crashes. Sometimes, my program even hangs instead of terminating.
Solution
RSB tries to clean up all created participants when a program terminates or crashes but this needs some support from the client program (and even then, not all languages support guaranteed cleanup e.g. in case of certain crashes).
The following idioms can be used to allow RSB to clean up properly:
Warning
The following idiom may hinder debugging because catching all exceptions prevents debuggers like gdb from seeing them. As a result, getting a backtrace most likely requires disabling the
try
/catch
block and recompiling the program.Avoid uncaught exceptions at the toplevel. This can be done by catching exceptions in
main()
:#include <unistd.h> #include <stdexcept> #include <iostream> // ... int main() { try { rsb::ListenerPtr listener = rsb::getFactory().createListener("/"); // Code using LISTENER goes here. } catch (const std::exception& e) { std::cerr << "Uncaught exception at toplevel: " << e.what() << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS; }See also
- Sending Data
- Python section of the basic tutorial
The context manager protocol should be used to ensure cleanup:
with rsb.createListener('/') as listener: # Code using LISTENER goes here passFor multiple participants use:
with rsb.createListener('/') as listener, rsb.createInformer('/') as informer: # Code using LISTENER and INFORMER goes here passMake sure that the
deactivate
method of participant objects is called:rsb.Listener listener; try { listener = rsb.Factory.getInstance().createListener("/"); listener.activate(); // Code using LISTENER goes here. } finally { if (listener != null) { try { listener.deactivate(); } catch (Exception e) { e.printStackTrace(); } } }Automatic cleanup is ensured when using the
rsb:with-active-participant
,rsb:with-participant
, etc. macros:(rsb:with-participant (listener :listener "/") ;; Code using LISTENER goes here. )