Menu

#3 Exception thrown while doing method call

open
Andreas
None
5
2012-10-03
2010-12-14
aurisc4
No

I'm trying to call some methods of Gnote note taking application. I tried some call, but Gnote closes because of uncaught exception, which seems to be thrown by dbus-c++ library.
I'm using Ubuntu 10.10, dbus-c++ version from repository, git master version of Gnote.

See this Gnote bug:
https://bugzilla.gnome.org/show_bug.cgi?id=618330

Stacktrace from Gnote:

0 0x01538075 in __cxa_throw () from /usr/lib/libstdc++.so.6

1 0x014dcfaf in std::__throw_logic_error(char const*) () from /usr/lib/libstdc++.so.6

2 0x081386d0 in std::basic_string<char, std::char_traits<char="">, std::allocator<char> >::_S_construct<char const*=""> (

__beg=0x0, __end=0xffffffff <Address 0xffffffff out of bounds>, __a=...)
at /usr/include/c++/4.4/bits/basic_string.tcc:134

3 0x0151b2f5 in std::basic_string<char, std::char_traits<char="">, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) () from /usr/lib/libstdc++.so.6

4 0x0030fc6e in DBus::ObjectAdaptor::handle_message(DBus::Message const&) () from /usr/lib/libdbus-c++-1.so.0

5 0x0030dde8 in DBus::ObjectAdaptor::Private::message_function_stub(DBusConnection, DBusMessage, void*) ()

from /usr/lib/libdbus-c++-1.so.0

6 0x0034af5e in ?? () from /lib/libdbus-1.so.3

7 0x0033ceb7 in dbus_connection_dispatch () from /lib/libdbus-1.so.3

8 0x00315c0c in ?? () from /usr/lib/libdbus-c++-1.so.0

9 0x0031a10e in DBus::Dispatcher::dispatch_pending() () from /usr/lib/libdbus-c++-1.so.0

10 0x00321870 in ?? () from /usr/lib/libdbus-c++-1.so.0

11 0x012d8855 in g_main_context_dispatch () from /lib/libglib-2.0.so.0

12 0x012dc668 in ?? () from /lib/libglib-2.0.so.0

13 0x012dcba7 in g_main_loop_run () from /lib/libglib-2.0.so.0

14 0x00b3a1d9 in gtk_main () from /usr/lib/libgtk-x11-2.0.so.0

15 0x005713b7 in Gtk::Main::run_impl() () from /usr/lib/libgtkmm-2.4.so.1

16 0x005711b2 in Gtk::Main::run() () from /usr/lib/libgtkmm-2.4.so.1

Please, ask for any additional information I may provide.

Discussion

  • Bigfoot

    Bigfoot - 2011-07-26

    Hi,

    Here is a small and simple programm I wrote to use dbus-c++.
    I wrote it to evidence a problem occuring when I use dbus, which seems very close to the one observed by aurisc4.
    To run this program, you need the media player «Banshee». Notice that you can addapt the programm to run with another player, I had the same behaviour with rhythmbox.

    What is the programm supposed to do?
    - it continuously ask the actual position in the current track played by banshee.
    - When the state of banshee changes, the new state is displayed on the terminal. This is done using a dbus signal.
    - When the program stops (Ctrl+C), the last position obtained from DBus is displayed, so that one can see that the method call correctly worked.

    Most of the time, the programm work correctly, but... not for long. Indeed, two bad things can occur:
    -(1) Segmentation fault while creating a new Proxy, at the very beginning of the execution.
    -(2) Segmentation fault after a dbus signal catch.

    concerning (1), I observed that the segmentation fault occurs when the proxy creation is performed while the dispatcher is running. I can't start and stop the dispatcher, if I stop it (using DBus::BusDispatcher::leave), I won't be able to start it again (with DBus::BusDispatcher::enter).
    concerning (2), I have no Idea. However, a backtrace sometimes appears and dispatcher functions are often (always?) displayed.

    Am I doing something wrong? Did I miss something?

    Here is the code (sorry, it seems that I can't upload a file):

    include <signal.h>

    include <stdio.h>

    include <stdlib.h>

    include <boost thread.hpp="">

    include <dbus dbus.h="">

    include <dbus-c++-1 dbus-c++="" dbus.h="">

    DBus::Connection gConnection = NULL;
    DBus::BusDispatcher gDispatcher;
    boost::thread
    gThrdDispatcher = NULL;
    bool gRun = true;

    class Plugin_Dbus_Proxy : public DBus::InterfaceProxy, public DBus::ObjectProxy
    {
    private:
    unsigned int _time; ///< current position in the track
    boost::mutex _mutex;
    public:
    /* Constructor
    * @param in_Connection : Connection used for the proxy
    * @param in_Path : Path to the device
    * @param in_Service : Service to connect to
    * @param in_Interface : Name of the interface
    /
    Plugin_Dbus_Proxy(DBus::Connection in_Connection, std::string in_Path,
    std::string in_Service, std::string in_Interface):
    DBus::InterfaceProxy(in_Interface),
    DBus::ObjectProxy(in_Connection, in_Path, in_Service.c_str()) {;}
    /// Destructor
    ~Plugin_Dbus_Proxy(){;}

    /// return the actual position in the current track.
    unsigned int get_Time()
    {
        unsigned int ans;
        _mutex.lock();
            ans = _time;
        _mutex.unlock();
        return ans;
    }
    
    /** CallBack of a signal note that the signal must contain a string
     *
     */
    void echo_Signal(const DBus::SignalMessage &sig)
    {
        std::cout << "signal catched" << std::endl;
    
        DBus::MessageIter it = sig.reader();
    
        std::string new_State; // string storing the signal value
        it >> new_State;
        std::cout << new_State << std::endl;
     }
    
    /** adds a signal to a proxy
     *
     *  @param in_Signal : name of the signal to connect to
     *
     *  @note It seems that the proxy will handle the deletion of the callback
     *  @return 0 on success, a negative value on error
     *
     */
    int add_Signal(std::string in_Signal)
    {
        _signals[in_Signal.c_str()] = new DBus::Callback<Plugin_Dbus_Proxy,void,const DBus::SignalMessage &>(this, &Plugin_Dbus_Proxy::echo_Signal);
       return 0;
    }
    
    /// invoke an arbitrary method, here, a property of banshee
    void invoke()
    {
        DBus::CallMessage call_Message;
        call_Message.member("GetPosition");
    
        // adds the parameter associated to the method (here no parameter are needed)
        call_Message.append( DBUS_TYPE_INVALID );
    
        // Get the reply of the method
        DBus::Message reply = invoke_method(call_Message);
    
        // Create a message iterator to read the reply
        DBus::MessageIter it = reply.reader();
    
        // Effectively read the reply (here an unsigned integer)
        unsigned int elapsed_Time;
        it >> elapsed_Time;
        _mutex.lock();
            _time = elapsed_Time;
        _mutex.unlock();
    }
    

    };

    void niam(int sig)
    {
    gRun = false;
    }

    int main(int argc, char **argv)
    {
    signal(SIGTERM, niam);
    signal(SIGINT, niam);

    // init
    DBus::default_dispatcher = &gDispatcher;
    gConnection = new DBus::Connection( DBus::Connection::SessionBus() );
    
    // start dispatcher in a thread
    gThrdDispatcher = new boost::thread( boost::bind( &DBus::BusDispatcher::enter, &gDispatcher) );
    
    // adding Proxies
    Plugin_Dbus_Proxy Plugin_Banshee( *gConnection, "/org/bansheeproject/Banshee/PlayerEngine", "org.bansheeproject.Banshee", "org.bansheeproject.Banshee.PlayerEngine");
    std::cout << "proxy 1 started" << std::endl;
    Plugin_Dbus_Proxy Plugin_Banshee2( *gConnection, "/org/bansheeproject/Banshee/ClientWindow", "org.bansheeproject.Banshee", "org.bansheeproject.Banshee.ClientWindow");
    std::cout << "proxy 2 started" << std::endl;
    
    // adding signal connection
    Plugin_Banshee.add_Signal("StateChanged");
    
    // main loop
    while(gRun)
    {
        Plugin_Banshee.invoke();
        usleep(10000);
    }
    
    std::cout << Plugin_Banshee.get_Time() << std::endl;
    
    gDispatcher.leave();
    gThrdDispatcher->join();
    delete gThrdDispatcher;
    delete gConnection;
    

    }

     
  • Andreas

    Andreas - 2011-11-28

    I couldn't compile your source code example. But I'll try to analyze it with your help.

    Could you compile dbus C library with gbd flags? In Ubuntu/debian it's possible to install debug symbols from apt-get. Please search google.

    But anyway please try to add a generic exception handler in ObjectAdaptor::handle_message(const Message &msg) after the two specific catch blocks and recompile. Only to see if this catches up your error and to analyze how dbus-c++ behaves after catching this. Please just add a error output on std out in the handler. In the next step we could think about how to handle the error correct and why it happens

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.