Archived

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

smart pointer list crash problem!

hi,in my project, there is a smart pointer list,that lots of smart pointer object will be inserted and then clear. It works fine for 1 day,today it crash on "list->push_back(ptr);".
attach is my picture of crash.
Why?and How to resolve it?

//smart pointer list
typedef vector<AgentMessage::TopdeskMessagePtr> AgentMessList;

//env
Ice: 3.1.0
Os: windows 2003 standard version
visual studio 2005


1 my code

typedef vector<AgentMessage::TopdeskMessagePtr> AgentMessList;
AgentMessList* list=new AgentMessList();
//create alarm message on stack
AgentMessage::agentAlarm::TopdeskProcessAlarm log;
log.dwRiskLevel = 3;
//....
TMCProcessAlarm::insert(list,&log);


//////////////////////////////////////////////////////////////////////////////
class TMCProcessAlarm{
public:
TMCProcessAlarm(){

}
static void insert(AgentMessList *list,AgentMessage::TopdeskMessage* mess)
{
if (mess && list){
AgentMessage::agentAlarm::TopdeskProcessAlarmPtr ptr
=new AgentMessage::agentAlarm::TopdeskProcessAlarm();

AgentMessage::agentAlarm::TopdeskProcessAlarm *pNote= dynamic_cast<AgentMessage::agentAlarm::TopdeskProcessAlarm*>(mess);
//copy
*ptr = *pNote;

list->push_back(ptr); //crash
}
}
}

2. my ice file

1) Message.ice:
#ifndef AGENT_MESSAGE_ICE
#define AGENT_MESSAGE_ICE
module AgentMessage{

class TopdeskMessage{
int messageType;
int subMessageType;
string agentID;
int agentType;
string agentIp;
string agentName;
long time;
int dwRiskLevel;
int dwPolicyID;
string description;
};
};
#endif

2) Alarm.ice
#include "Message.ice"
#ifndef AGENT_ALARM_ICE
#define AGENT_ALARM_ICE
module AgentMessage{
module agentAlarm{
class TopdeskProcessAlarm extends TopdeskMessage{
int dwReason;
string procName;
int dwProcID;
int dwcpuusage;
int dwRAMusage;
};
};
};
#endif




Thanks.
__________________
smith jason
Programmer/Analyst
TMC Project
Topsec network security company, beijing,100082

Comments

  • mes
    mes California
    Hi Jason,

    In C++, instances of Slice classes are reference-counted objects, and as a result you must allocate them dynamically (see this FAQ for an explanation).

    I suggest that you change your code as follows:
    AgentMessage::agentAlarm::TopdeskProcessAlarmPtr log =
        new AgentMessage::agentAlarm::TopdeskProcessAlarm;
    log->dwRiskLevel = 3;
    //....
    TMCProcessAlarm::insert(list, log);
    ...
    static void insert(
        AgentMessList *list,
        const AgentMessage::TopdeskMessagePtr& mess)
    {
        if (mess && list) {
            AgentMessage::agentAlarm::TopdeskProcessAlarmPtr pNote =
                AgentMessage::agentAlarm::TopdeskProcessAlarmPtr::dynamicCast(mess);
            assert(pNote); // dynamicCast may return nil!
            list->push_back(pNote);
        }
    }
    
    Hope that helps,
    - Mark
  • allocate C++ Slice classes.

    thank you !
    but,I has allocate c++ Slice classes in my code below,why it will crash?

    typedef vector<AgentMessage::TopdeskMessagePtr> AgentMessList;
    AgentMessList* list=new AgentMessList();
    //create alarm message on stack
    AgentMessage::agentAlarm::TopdeskProcessAlarm log;
    log.dwRiskLevel = 3;
    //....
    TMCProcessAlarm::insert(list,&log);

    ========================================================
    static void insert(AgentMessList *list,AgentMessage::TopdeskMessage* mess)
    {

    AgentMessage::agentAlarm::TopdeskProcessAlarmPtr ptr
    =new AgentMessage::agentAlarm::TopdeskProcessAlarm();


    AgentMessage::agentAlarm::TopdeskProcessAlarm *pNote= dynamic_cast<AgentMessage::agentAlarm::TopdeskProc essAlarm*>(mess);

    //copy
    *ptr = *pNote;
    list->push_back(ptr); //crash

    }
    Thanks.
    __________________
    smith jason
    Programmer/Analyst
    TMC Project
    Topsec network security company, beijing,100082
  • benoit
    benoit Rennes, France
    Hi,

    As Mark explained, you can't allocate on the stack instances of Slice classes. Allocating the instance on the stack might be the reason of the crash so you should first fix your code as Mark mentioned.

    If it still crashes once your code is fixed, please send us the stack trace of the crash along with the source code invovled in the crash.

    Cheers,
    Benoit.
  • Pages 228 and 229 in the Ice manual provide a detailed explanation of why stack-allocated class instances inevitably cause a crash.

    Cheers,

    Michi.
  • matthew
    matthew NL, Canada
    Although I don't think your code is a good idea, its not clear really why it crashes. I just tried a similar example with Ice 3.1.1 and it does not crash... hence something else must be going on in your code. I modified the hello demo client as follows:
    // Hello.ice
    class Bar
    {
        int xx;
    };  
        
    class Foo extends Bar
    {   
        int level;
    };
    
    // Client.cpp
    #include <list>
    void
    test(list<FooPtr>* l, Bar* f)
    {
        FooPtr ff = new Foo();
        Foo* realF = dynamic_cast<Foo*>(f);
        assert(realF);
        *ff = *realF;
        l->push_back(ff);
    }
    
    int
    HelloClient::run(int argc, char* argv[])
    {
        Foo f;
        f.xx = 0;
        f.level = 1;
        list<FooPtr> l;
        test(&l, &f);
        return EXIT_SUCCESS;
    }
    

    Furthermore, as of Ice 3.2 it will not be possible to create a class instance on the stack at all (the code will not compile).
  • can static class allocate Slice classes instances?

    thanks to everybody!
    matthew, as you said ,my code is not a good idear. But in my project, i cannot ensure that every coder will not allocate Slice classes instances on stack. So I design a static class TMCProcessAlarm to ensure every Slice classes instance on heap. ( TMCProcessAlarm::insert() method)
    My code work fine for about 10 hours, but finally it crash .
    After reading Ice manual and FAQ, I think that static class TMCProcessAlarm maybe a reason of crash, is it right?
    Now i has redesigned my code,it working again. I will post the test result here!

    thanks.
    __________________
    smith jason
    Programmer/Analyst
    TMC Project
    Topsec network security company, beijing,100082
  • You can have a static object refer to Ice classes, but you must make sure that all smart pointers to class instances are released before you finalize the run time. Otherwise, your program will suffer undefined behavior.

    Specifically, the constructor and destructor of class instances update a data structure in the Ice run time. If a class destructor runs after you have finalized the Ice run time and after main() has returned, the data structure that the destructor accesses may no longer be there because it is defined in a different compilation unit.

    In general, you should never have a static instance refer to anything in a different compilation unit, due to the undefined order of destruction of global objects in different compilation units.

    Cheers,

    Michi.
  • Maybe it is unsafe to allocate Slice classes instances in a static method
    of multithread application.
    Now,My code has worked for 15 hours,and it works fine.


    __________________
    smith jason
    Programmer/Analyst
    TMC Project
    Topsec network security company, beijing,100082
  • If there is a problem related to ordering of static destructors, your process should crash while it shuts down, not while it is runing.

    You might also consider using Purify, which is excellent at tracking down the cause of mysterious crashes.

    Cheers,

    Michi.