LoadLibrary fails - one or more arguments are invalid

G

Guest

I have a dll that was working in VC6, but isn't loading after being built in
VC71. LoadLibrary() returns null and the error code (from GetLastError()) is
-2147483645 "One or more arguments are invalid".

If I use LoadLibraryEx(dll,NULL,DONT_RESOLVE_DLL_REFERENCES) it loads fine
(returns non-null). I've looked in Dependency Walker and it doesn't show any
missing dependencies.

The DllMain in this dll has been pared down to a simple "return 1".

I don't know how else to go about figuring out what is wrong with my dll.
Perhaps there are preprocessor defs or other project settings that I can play
with? Are there other tools I can use to figure out what's happening?

Tomrmgc
 
R

Ronald Laeremans [MSFT]

tomrmgc said:
I have a dll that was working in VC6, but isn't loading after being built in
VC71. LoadLibrary() returns null and the error code (from GetLastError()) is
-2147483645 "One or more arguments are invalid".

If I use LoadLibraryEx(dll,NULL,DONT_RESOLVE_DLL_REFERENCES) it loads fine
(returns non-null). I've looked in Dependency Walker and it doesn't show any
missing dependencies.

The DllMain in this dll has been pared down to a simple "return 1".

I don't know how else to go about figuring out what is wrong with my dll.
Perhaps there are preprocessor defs or other project settings that I can play
with? Are there other tools I can use to figure out what's happening?

Tomrmgc
Hi,


Can you try using a tool like filemon (ftom http://www.sysinternals.com)
or another tool with similar funcationality to show you what the loader
is trying to read in from the file system? That has worked before for me
in figuring out what isn;t resolving.

Ronald Laeremans
Visual C++ team
 
G

Guest

Ronald Laeremans said:
Hi,


Can you try using a tool like filemon (ftom http://www.sysinternals.com)
or another tool with similar funcationality to show you what the loader
is trying to read in from the file system? That has worked before for me
in figuring out what isn;t resolving.

Ronald Laeremans
Visual C++ team

Thanks for the reply. Filemon showed there to be only one dll not found
(UXTHEME.DLL) and I don't see anywhere in my code that explicitly loads that.
All of the other dlls it found (and in the right place).

I tried adding an exit at the beginning of DllMain but it never gets there.
How do I find out what is going on during the load that can cause this error?
By the way, I have a couple of other dlls in the same solution that load just
fine. Any other ideas?

Thanks,
TomR
 
O

Oleg Starodumov

Try to enable loader snaps:

HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\YourApp.exe
GlobalFlag = REG_DWORD 0x2
(replace "YourApp" with the name of the executable that loads the DLL)

(Or check "Show loader snaps" for the executable in GFlags tool, if you have it).

Then run the executable under debugger and see messages from the loader
in Debug Output window.

Regards,
Oleg
 
Y

Yan-Hong Huang[MSFT]

Hi TomR,

For detailed steps on how to use "Image File Execution Options", please
refer to http://blogs.msdn.com/greggm/archive/2005/02/21/377663.aspx.

Although this feature is for debugging, it is really just a general
mechanism of redirecting what application gets launched, which is kind of
interesting. :)

Hope that helps.

Best regards,
Yanhong Huang
Microsoft Community Support

Get Secure! ¨C www.microsoft.com/security
Register to Access MSDN Managed Newsgroups!
-http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.as
p&SD=msdn

This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Yan-Hong Huang said:
Hi TomR,

For detailed steps on how to use "Image File Execution Options", please
refer to http://blogs.msdn.com/greggm/archive/2005/02/21/377663.aspx.

Although this feature is for debugging, it is really just a general
mechanism of redirecting what application gets launched, which is kind of
interesting. :)

Hope that helps.

Best regards,
Yanhong Huang
Microsoft Community Support

Thanks to all the replies. With everyone's assistance I have managed to
track down the culprit in the loading of the DLL, but now I'm not quite sure
why this isn't working (no change from vc6 where it was working).

The error occurs during initialization but before DllMain gets called. In
the construction of a class, the function foo() gets called (obviously pared
way down).
It appears scutTable isn't being initialized. Any attempt to access it or
any members causes an access violation.

Do you have any idea why this behavior has changed and suggestions on the
best way to get the initialization to happen? Should I create a static
function to initialize it?

Thanks,
TomR

static struct Entry {
CString str;
UINT mod;
Entry(LPCTSTR a_str, UINT a_mod)
{
str = a_str;
mod = a_mod;
}
} scutTable[] = {
Entry("Alt+", FALT),
Entry("Ctrl+", FCONTROL),
Entry("Shift+", FSHIFT),
Entry("LButton+", FLBUTTON),
Entry("MButton+", FMBUTTON),
Entry("RButton+", FRBUTTON)
};

void foo()
{
CString myEntryString = scutTable[0].str; // Causes access violation
}
 
R

Ronald Laeremans [MSFT]

Thanks to all the replies. With everyone's assistance I have managed to
track down the culprit in the loading of the DLL, but now I'm not quite sure
why this isn't working (no change from vc6 where it was working).

The error occurs during initialization but before DllMain gets called. In
the construction of a class, the function foo() gets called (obviously pared
way down).
It appears scutTable isn't being initialized. Any attempt to access it or
any members causes an access violation.

Do you have any idea why this behavior has changed and suggestions on the
best way to get the initialization to happen? Should I create a static
function to initialize it?

Thanks,
TomR

static struct Entry {
CString str;
UINT mod;
Entry(LPCTSTR a_str, UINT a_mod)
{
str = a_str;
mod = a_mod;
}
} scutTable[] = {
Entry("Alt+", FALT),
Entry("Ctrl+", FCONTROL),
Entry("Shift+", FSHIFT),
Entry("LButton+", FLBUTTON),
Entry("MButton+", FMBUTTON),
Entry("RButton+", FRBUTTON)
};

void foo()
{
CString myEntryString = scutTable[0].str; // Causes access violation
}

How does foo get called before DLLMain is executed? In what translation
unit is the call to foo?

Ronald
 
G

Guest

tomrmgc said:
Yan-Hong Huang said:
Hi TomR,

For detailed steps on how to use "Image File Execution Options", please
refer to http://blogs.msdn.com/greggm/archive/2005/02/21/377663.aspx.

Although this feature is for debugging, it is really just a general
mechanism of redirecting what application gets launched, which is kind of
interesting. :)

Hope that helps.

Best regards,
Yanhong Huang
Microsoft Community Support

Thanks to all the replies. With everyone's assistance I have managed to
track down the culprit in the loading of the DLL, but now I'm not quite sure
why this isn't working (no change from vc6 where it was working).

The error occurs during initialization but before DllMain gets called. In
the construction of a class, the function foo() gets called (obviously pared
way down).
It appears scutTable isn't being initialized. Any attempt to access it or
any members causes an access violation.

Do you have any idea why this behavior has changed and suggestions on the
best way to get the initialization to happen? Should I create a static
function to initialize it?

Thanks,
TomR

static struct Entry {
CString str;
UINT mod;
Entry(LPCTSTR a_str, UINT a_mod)
{
str = a_str;
mod = a_mod;
}
} scutTable[] = {
Entry("Alt+", FALT),
Entry("Ctrl+", FCONTROL),
Entry("Shift+", FSHIFT),
Entry("LButton+", FLBUTTON),
Entry("MButton+", FMBUTTON),
Entry("RButton+", FRBUTTON)
};

void foo()
{
CString myEntryString = scutTable[0].str; // Causes access violation
}

Sorry to followup my own post, but I found out a little bit more
information. It appears the CString is not getting initialized. If I have a
static variable that is an int, it gets initialized. If I have a static
variable that is a CString, it does NOT get initialized. Is this
known/expected behavior?
 
G

Guest

Ronald Laeremans said:
Thanks to all the replies. With everyone's assistance I have managed to
track down the culprit in the loading of the DLL, but now I'm not quite sure
why this isn't working (no change from vc6 where it was working).

The error occurs during initialization but before DllMain gets called. In
the construction of a class, the function foo() gets called (obviously pared
way down).
It appears scutTable isn't being initialized. Any attempt to access it or
any members causes an access violation.

Do you have any idea why this behavior has changed and suggestions on the
best way to get the initialization to happen? Should I create a static
function to initialize it?

Thanks,
TomR

static struct Entry {
CString str;
UINT mod;
Entry(LPCTSTR a_str, UINT a_mod)
{
str = a_str;
mod = a_mod;
}
} scutTable[] = {
Entry("Alt+", FALT),
Entry("Ctrl+", FCONTROL),
Entry("Shift+", FSHIFT),
Entry("LButton+", FLBUTTON),
Entry("MButton+", FMBUTTON),
Entry("RButton+", FRBUTTON)
};

void foo()
{
CString myEntryString = scutTable[0].str; // Causes access violation
}

How does foo get called before DLLMain is executed? In what translation
unit is the call to foo?

Ronald

In one of the class constructors, foo is called (although a few levels down).

I'm not totally sure how to answer the last question. The file
UI_CommandManager.cpp contains a call to foo (which is in UI_HotKeyCtrl.cpp).
Would a copy of the call stack be meaningful?

To followup to my other post, I have another static struct in
UI_HotKeyCtrl.cpp that only contains int's and it gets initialized just fine.
For some reason the CStrings don't get initialized.

TomR
 
O

Oleg Starodumov

Sorry to followup my own post, but I found out a little bit more
information. It appears the CString is not getting initialized. If I have a
static variable that is an int, it gets initialized. If I have a static
variable that is a CString, it does NOT get initialized. Is this
known/expected behavior?

Yes, the problem seems to be with the order in which the constructors of
global/static objects are called. Probably constructors of some objects
attempt to use other objects _before_ their constructors have been executed
(and thus the objects are not yet initialized).

I would recommend to move the initialization of the DLL's global state
into dedicated functions that should be called by the user of the DLL.
Then you will be able to control the order in which the objects are initialized.

Regards,
Oleg
 
G

Guest

Oleg Starodumov said:
Yes, the problem seems to be with the order in which the constructors of
global/static objects are called. Probably constructors of some objects
attempt to use other objects _before_ their constructors have been executed
(and thus the objects are not yet initialized).

I would recommend to move the initialization of the DLL's global state
into dedicated functions that should be called by the user of the DLL.
Then you will be able to control the order in which the objects are initialized.

Regards,
Oleg

I agree it appears this is what is happening. I wish Microsoft would have
been a little more proactive in documenting changes such as these. Not only
would it confirm what I'm seeing but it would have prevented me from bashing
my head against a brick wall for the last week.

TomR
 
R

Ronald Laeremans [MSFT]

tomrmgc said:
:




I agree it appears this is what is happening. I wish Microsoft would have
been a little more proactive in documenting changes such as these. Not only
would it confirm what I'm seeing but it would have prevented me from bashing
my head against a brick wall for the last week.

TomR
Statics in one compiland are initialized in the order they are
encountered. Statics accross compilands ar initialized in what is
essentially a random order. There are directives that normally make sure
CRT and other libraries initialize first (see #pragma init_seg).

In short the code probably has a dependency on undefined behavior and
undefined behavior does change between versions.

Ronald Laeremans
Visual C++ team
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top