|
From: Dirk L. <di...@no...> - 2003-02-27 12:39:16
|
Hi, today I had a strange problem with the Categroy::getAllAppenders () function. I'm writing a small gui dialog to customize the logging during the execution of the program. Right now I can edit the categories with the vector returned from getCurrentCategories (). I wanted to display also the list of attached appenders so I asked for the AppenderSet via the function getAllAppenders (). But the returned set is not valid, since the implementation of the _Tree used in the std::set contains a static _Nil node, which is not the same in the process and in the DLL. As a result when I try to iterate the returned set I get an invalid AppenderSet::end () iterator and the iteration continues until the software crashes. Perhaps as little longer description: the STL implementation of the std::set in Microsoft uses a std::_Tree. The std::_Tree maintains one static _Nil and one static _Nilrefs member, that is used to mark the ends in the trees. This _Nil is used in within all _Trees with the same template arguments. Compiling log4cpp as a DLL will result in having one static instance of these to members within the DLL, that are not the same static instances of theses members in the Application. So copying the AppenderSet within the context of the DLL will use the DLLs instance of the _Nil pointer to mark the ends in the _Tree. But iterating through the std::set within the application context will result in the usage of a different _Nil element. So the iteration through the _Tree will never end, since the end of the _Tree will never match the _Nil element. Any ideas how to circumvent the problem? Thanks Dirk |
|
From: Dirk L. <di...@no...> - 2003-02-27 13:03:22
|
A question and an answer: As usual after finding the error, explaning it to others one also finds the right words to search the net for solutions. I found two MSDN articles describing the problem: --- http://support.microsoft.com/default.aspx?scid=KB;en-us;q172396 SYMPTOMS When accessing an STL object created in one DLL or EXE through a pointer or reference in a different DLL or EXE, you may experience an access violation or other serious program errors including the appearance of data corruption or data loss. --- http://support.microsoft.com/default.aspx?scid=kb;EN-US;168958 SUMMARY This article demonstrates how to: * Export an instantiation of a Standard Template Library (STL) class. * Export a class that contains a data member that is an STL object. Note that you may not export a generalized template. The template must be instantiated; that is, all of the template parameters must be supplied and must be completely defined types at the point of instantiation. For instance "stack<int>;" instantiates the STL stack class. The instantiation forces all members of class stack<int> to be generated. Also note that some STL containers (map, set, queue, list, deque) cannot be exported. Please refer to the More Information section to follow for a detailed explanation. ... a little later ... The only STL container that can currently be exported is vector. ... --- The bottom line is: getAllAppenders _must_ generate a std::vector from the std::set like getCurrentCategories() to safely export the list of appenders. I would like to give provide you with a patch for this change. Do you prefer specific parameters for the diff command? Dirk Dirk Luetjens wrote: > Hi, > > today I had a strange problem with the Categroy::getAllAppenders () > function. I'm writing a small gui dialog to customize the logging during > the execution of the program. Right now I can edit the categories with > the vector returned from getCurrentCategories (). I wanted to display > also the list of attached appenders so I asked for the AppenderSet via > the function getAllAppenders (). But the returned set is not valid, > since the implementation of the _Tree used in the std::set contains a > static _Nil node, which is not the same in the process and in the DLL. > As a result when I try to iterate the returned set I get an invalid > AppenderSet::end () iterator and the iteration continues until the > software crashes. > > Perhaps as little longer description: the STL implementation of the > std::set in Microsoft uses a std::_Tree. The std::_Tree maintains one > static _Nil and one static _Nilrefs member, that is used to mark the > ends in the trees. This _Nil is used in within all _Trees with the same > template arguments. Compiling log4cpp as a DLL will result in having one > static instance of these to members within the DLL, that are not the > same static instances of theses members in the Application. So copying > the AppenderSet within the context of the DLL will use the DLLs instance > of the _Nil pointer to mark the ends in the _Tree. But iterating through > the std::set within the application context will result in the usage of > a different _Nil element. So the iteration through the _Tree will never > end, since the end of the _Tree will never match the _Nil element. > > > Any ideas how to circumvent the problem? |
|
From: Aaron I. <ai...@ya...> - 2003-02-27 19:42:29
|
No real standard but "-Naur" seems to be preferred. -Aaron Dirk Luetjens <di...@no...> wrote:A question and an answer: As usual after finding the error, explaning it to others one also finds the right words to search the net for solutions. I found two MSDN articles describing the problem: --- http://support.microsoft.com/default.aspx?scid=KB;en-us;q172396 SYMPTOMS When accessing an STL object created in one DLL or EXE through a pointer or reference in a different DLL or EXE, you may experience an access violation or other serious program errors including the appearance of data corruption or data loss. --- http://support.microsoft.com/default.aspx?scid=kb;EN-US;168958 SUMMARY This article demonstrates how to: * Export an instantiation of a Standard Template Library (STL) class. * Export a class that contains a data member that is an STL object. Note that you may not export a generalized template. The template must be instantiated; that is, all of the template parameters must be supplied and must be completely defined types at the point of instantiation. For instance "stack;" instantiates the STL stack class. The instantiation forces all members of class stack to be generated. Also note that some STL containers (map, set, queue, list, deque) cannot be exported. Please refer to the More Information section to follow for a detailed explanation. ... a little later ... The only STL container that can currently be exported is vector. ... --- The bottom line is: getAllAppenders _must_ generate a std::vector from the std::set like getCurrentCategories() to safely export the list of appenders. I would like to give provide you with a patch for this change. Do you prefer specific parameters for the diff command? Dirk Dirk Luetjens wrote: > Hi, > > today I had a strange problem with the Categroy::getAllAppenders () > function. I'm writing a small gui dialog to customize the logging during > the execution of the program. Right now I can edit the categories with > the vector returned from getCurrentCategories (). I wanted to display > also the list of attached appenders so I asked for the AppenderSet via > the function getAllAppenders (). But the returned set is not valid, > since the implementation of the _Tree used in the std::set contains a > static _Nil node, which is not the same in the process and in the DLL. > As a result when I try to iterate the returned set I get an invalid > AppenderSet::end () iterator and the iteration continues until the > software crashes. > > Perhaps as little longer description: the STL implementation of the > std::set in Microsoft uses a std::_Tree. The std::_Tree maintains one > static _Nil and one static _Nilrefs member, that is used to mark the > ends in the trees. This _Nil is used in within all _Trees with the same > template arguments. Compiling log4cpp as a DLL will result in having one > static instance of these to members within the DLL, that are not the > same static instances of theses members in the Application. So copying > the AppenderSet within the context of the DLL will use the DLLs instance > of the _Nil pointer to mark the ends in the _Tree. But iterating through > the std::set within the application context will result in the usage of > a different _Nil element. So the iteration through the _Tree will never > end, since the end of the _Tree will never match the _Nil element. > > > Any ideas how to circumvent the problem? ------------------------------------------------------- This SF.NET email is sponsored by: SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See! http://www.vasoftware.com _______________________________________________ Log4cpp-devel mailing list Log...@li... https://lists.sourceforge.net/lists/listinfo/log4cpp-devel --------------------------------- Do you Yahoo!? Yahoo! Tax Center - forms, calculators, tips, and more |