arm-wince-[gcc|binutils|newlib] and dll loader debugging

"pedrompalves" <[email protected]> Sun, 16 Oct 2005 23:59:30 -0000
Newsgroups gmane.comp.windows.ce.freeware
Message-ID <[email protected]>
Hi guys.
Continuing my quest to port Qt4 to windows ce.

I had been using the toolchain from Mamaich's page, and it was going
fairly well, until I got tired of the long link times using a static
Qt version.
I wanted to build Qt as a dll, only to stumble on a lot of nuances.
I finally decided to try building more recent versions of
binutils/newlib/gcc.

I had to learn more of the internals of gnu tools than I wanted in the
first place, but I am *almost* happy with the result.

as a summary:

I have newlib recent cvs with voxware/mamaich's wince stuff working.
binutils 20050201 with some hacks, that need a lot of clean up, but
are ok for now. couldn't get a recent version to run ok, cause the arm
stuff changed to much. Will look at it later.
The gcc I am targetting is gcc4.1cvs
The -staticlibs is no longer needed. global c++ constructors are now
called even when using -lcdll
-target=* is not needed anymore
implemented c++ classes dllimport/dllexport for arm,
added pragma pack/push support

Qt builds and runs as a static lib, but as a dll, it is not quite
there yet because of the following problem.

I am now stuck on what I think is a loader deadlock.

I made a test case that shows the problem. Maybe someone can give me a
direction on where should I be looking.

I have a dll which defines:

class testcpp
{
public:
	testcpp()
	{
	 printf("dll: in cc\n"); // commenting this out works
	}
	~testcpp()
	{
	printf("in ~cc\n");
	}
};

//global, __gccmain takes care of it
testcpp c;

extern "C" __declspec(dllexport) void hello()
{
    testcpp d;
    printf("dll: hello world\n", a);
    MessageBoxW(0, L"hello dll world", L"dll", 0);
}

-----------------------------

In the Dll entry point (DllMainCRTStartup) I call __gccmain
I have a test app that is basically:

extern "C" __declspec(dllimport) void hello();

extern "C" int main(int argc, char**argv)
{
  printf("in main\n");
  hello();
  return 0;
}

----------------------------

The thing is, that printf called from a global constructor in the dll
makes the app not load, leaving the pda in what looks like a loader
deadlock. From this point on I can't run any app, and I have to soft
reset the device. I can see with gdb that the app does not load a
single dll with the printf there. gdb says forever: "Waiting for
connection...".

If I remove the printf, gdb shows me this loading sequence:
Waiting for connection...
af1000:libc.dll
f01000:mydll.dll
3081000:iphlpapi.dll
3061000:ws2.dll
3071000:winsock.dll
7ffe1000:coredll.dll.0409.mui
1f61000:coredll.dll

And the app runs fine.

I tracked the deadlock to:

mydll.dll entry point (global loader lock)
-> __gccmain 
->testcpp global cc
->any funcion in libcdll.dll that call any function in
->coredll.dll

if I call directly any coredll.dll function it runs ok.

eg:

class testcpp {
public: testcpp()
{
 _getstdfilex(0);
}
};

is ok, but if I export a function in libcdll that only calls
_getstdfilex and call it from mydll, it locks!

Now to the questions:

1. Is there any way to debug these loader problems in windows ce?
2. Anyone interested in trying out this toolchain?
   I can post the patches somewhere, but I don't have a webpage, so 
3. Anyone know a nice free webhosting so I can upload the toolchain?

Cheers,
Pedro Alves





------------------------ Yahoo! Groups Sponsor --------------------~--> 
Fair play? Video games influencing politics. Click and talk back!
http://us.click.yahoo.com/T8sf5C/tzNLAA/TtwFAA/W4wwlB/TM
--------------------------------------------------------------------~->