1.7.9: static const std::string initialization lost in child process when using fork, dlopen

whans@web.de whans@web.de
Sun Aug 21 11:48:00 GMT 2011


Hello,
 
it seems that a child process does not see the initialization of a
static const std::string variable if it is defined in a dll. Instead this corrupt variable
lead to a STATUS_ACCESS_VIOLATION.
 
The following 4 example files demonstrate this behaviour:
 
1) dllif.h:      (define the dll's interface)
#include <string>
class cTestIf {
public:
  virtual std::string get() = 0;
};
 
 
2) dll.h:        (member variable t will cause the child's stackdump)
#include "dllif.h"
class cTest : public cTestIf {
public:
  static const std::string t;
  virtual std::string get() {
      return cTest::t;
  }
};
 
 
3) dll.cpp      (definition of dll including initializer of t)
#include "dll.h"
const std::string cTest::t = "Test";
 
extern "C" cTest* getTest() {
   return new cTest();
}
 
 
4) test.cpp    (fork child, load dll and print cTest::t both in parent and child)
#include <unistd.h>
#include <dlfcn.h>
#include "dllif.h"
#include <iostream>
 
typedef cTestIf *(*tFunc)();
 
void load(const char *p) {
  void* lib = dlopen("libdll.dll", RTLD_NOW|RTLD_GLOBAL);
  tFunc func = (tFunc)dlsym(lib, "getTest");
  cTestIf* test = func();
  std::cerr << p << ":" << test->get() << "\n";
}
 
main() {
   if (fork())
      load("parent");
   else {
      sleep(30);  // keep child alive to enable attachment from gdb
      load("child");
   }
}
 
 
 
commands used to create dll and test program:
g++ -g -c dll.cpp -o dll.o
g++ -shared -o libdll.dll dll.o
g++ -g -c test.cpp -o test.o
g++ -o test test.o -L. -ldll
 
 
./test.exe prints only 'parent:Test' - parent works as expected - and gives a
test.exe.stackdump - after 30 seconds.
 
 
an example gdb session looks like:
attach <child pid>
b load
c           (needs up to 30 seconds for return)
n
n
n
s           (step into dll's cTest::get method)
p t         (print cTest::t, _M_p seems to be corrupt)
$1 = {static npos = <optimized out>,
  _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<
No data fields>}, <No data fields>}, _M_p = 0x0}}
n
Program received signal SIGSEGV, Segmentation fault.
0x6c4b95be in cygstdc++-6!_ZNSsC1ERKSs () from /usr/bin/cygstdc++-6.dll
 
 Any idea to fix or circumvent this error?

Regards,
Werner
___________________________________________________________
Schon gehört? WEB.DE hat einen genialen Phishing-Filter in die
Toolbar eingebaut! http://produkte.web.de/go/toolbar
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test.exe.stackdump
Type: application/octet-stream
Size: 636 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin/attachments/20110821/634c319c/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cygcheck.out
Type: application/octet-stream
Size: 28601 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin/attachments/20110821/634c319c/attachment-0001.obj>
-------------- next part --------------
--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple


More information about the Cygwin mailing list