Archived

This forum has been archived. Please start a new discussion on GitHub.

SegFault problems with Proxies

Hi

The program I'm writing is intended to be used by a lot of people, who will merge it with their own code. Since I can't controll the behaviour of this code, I'm testing my program for robustness to check how it behaves in the case of local failure.

Unfortunatly I'm encountering problems, I don't understand:

After the Server has "crashed"(using abort(), NO Shutdown of the Ice::Communicator), sometimes the proxies on the clientside are causing segmentation faults, if

1. I call a method on the proxy
2. the Proxy is destroyed.

Is there a way for me to ensure, that a local failure does not propagate and cause failures in other Processes as well?
Ideally I would expect to get a ConnectionLostException in EVERY case I'm trying to access the proxy.
At the moment I'm a bit confused by this behaviour.

Thanx in advance

Gerald

Comments

  • The client should not crash because the server crashes. You should get a ConnectFailedException or ConnectionLostException. You can test this with all the demos. For example, with the demo in demo/Ice/hello: Kill the server, and the client will report an exception when you try to send a request to the server.

    I'm not aware of any problems in Ice that could cause a segmentation fault instead of an exception. I'm afraid without a code example, I cannot give much advice.
  • Hi, thanx for the answer.

    I know, this shouldn't happen, that's why I'm confused :)

    This is a SHORT Version of the Code.

    void ObjectX::registerInterceptor(const InterceptorPrx& proxy, const Ice::Current&) {
    IceUtil::RecMutex::Lock lock(_mutex);

    //More happening here, this is just a short version

    //proxy is a oneway-proxy
    _interceptors.push_back(proxy);
    }


    void ObjectX::somethingHappens() {

    //More happening here

    IceUtil::RecMutex::Lock lock(_mutex);

    std::list<InterceptorPrx>::iterator k;
    for (k = _interceptors.begin(); k != _interceptors.end(); k++) {
    try {
    //SEGFAULT
    (*k)->somethingHappens();
    }catch(const Ice::Exception&) {
    _interceptors.erase(k);
    }}}

    The Stacktrace looks like this:

    ObjectX::somethingHappens() at *MY CODE*
    IceProxy::Interceptor::somethingHappens() at *GENERATED CODE*
    IceProxy::Ice::Object::__defaultContext() at Proxy.cpp:836
    IceUtil::HandleBase<IceInternal::Reference>::operator->() at Handle.h:42

    Thanx in Advance

    Gerald
  • I believe this is a problem with the erase() in the for-loop. Unfortuantely, I don't have my copy of "Effective STL" handy, but I believe the code should look like this:

    std::list<InterceptorPrx>::iterator k = _interceptors.begin();
    while(k != _interceptors.end())
    {
    try
    {
    (*k)->somethingHappens();
    ++k;
    }
    catch(const Ice::Exception&)
    {
    _interceptors.erase(k++);
    }
    }

    The problem with just doing a erase(k) is that this invalidates the iterator, and thus the next k++ fails. By using erase(k++), a temporary is passed to erase, and the iterator is not invalidated.

    Of course this doesn't have anything to do with Ice :)
  • looks like problem in app code
    Originally posted by galbe

    std::list<InterceptorPrx>::iterator k;
    for (k = _interceptors.begin(); k != _interceptors.end(); k++) {
    try {
    //SEGFAULT
    (*k)->somethingHappens();
    }catch(const Ice::Exception&) {
    _interceptors.erase(k);
    }}}

    Looks like its a problem in the application code. Lets assume that the remote app is down. You'd then get an exception, at which point you're doing

    _interceptors.erase(k);

    As soon as this is done, 'k' becomes invalid. After this again you're doing 'k++', as part of the 'for' statement. Thus, in the next iteration of the loop you'll referencing invalid memory.

    That could be one of the reasons why you're getting a segfault
  • Thanx for your help.