• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2245
  • Last Modified:

Yet Another LNK4098

I know it's a common question and typically an easy answer, but I still cannot solve it.  Perhaps it is something special or I missed it.

MSVC++ 6.0
Win2K
Compiling in Release Mode
Project has two separate DLLs and a LIB, in addition to the main project.  From what I can see, only the /MD option is used, never /MDd.  The Code Generation uses only Multithreaded DLLs (for all projects).  I've even tried putting MSVCRTD (and MFC42D and MFCS42D) in the ignore libraries option input in the Link tab.  I still get:

defaultlib 'MSVCRTD' conflicts with use of other libs; use /NODEFAULTLIB:library
defaultlib 'mfc42d.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
defaultlib 'mfcs42d.lib' conflicts with use of other libs; use /NODEFAULTLIB:library

The Dependency Walker shows the app using both msvcrt.dll and msvcrtd.dll, and MFC42.DLL and MFC42D.DLL.  I think I've tried just about every combination of options to eliminate this error (rebuilding all each time), and no dice.
0
Infiniti2000
Asked:
Infiniti2000
  • 11
  • 7
  • 4
1 Solution
 
jkrCommented:
Are you linking eith a 3rd party component/lib that was compiled in 'debug' mode? If not, use the 'Profile' option of the dependency walker to track what module is loading the debg versions of the MS DLLs.
0
 
Infiniti2000Author Commented:
To my knowledge, no.  I am using only one third party lib and it only references MSVCRT.DLL, not the debug version.  The dependency walker has no profile option that I can see, but if turn on "print progress" from the Link tab, I get the following for the first reference of msvcrtd:

    Searching C:\Program Files\Microsoft Visual Studio\VC98\LIB\msvcirtd.lib:
    Searching C:\Program Files\Microsoft Visual Studio\VC98\LIB\MSVCRTD.lib:
      Found __imp___stricmp
        Referenced in OLDNAMES.lib(stricmp.obi)
        Loaded MSVCRTD.lib(MSVCRTD.dll)
      Found __imp___itoa
        Referenced in OLDNAMES.lib(itoa.obi)
        Loaded MSVCRTD.lib(MSVCRTD.dll)
      Found __IMPORT_DESCRIPTOR_MSVCRTD
        Referenced in MSVCRTD.lib(MSVCRTD.dll)
        Referenced in MSVCRTD.lib(MSVCRTD.dll)
        Loaded MSVCRTD.lib(MSVCRTD.dll)
      Found MSVCRTD_NULL_THUNK_DATA
        Referenced in MSVCRTD.lib(MSVCRTD.dll)
        Loaded MSVCRTD.lib(MSVCRTD.dll)
    Searching C:\Program Files\Microsoft Visual Studio\VC98\MFC\LIB\mfc42d.lib:
      Found "public: void __thiscall CWnd::Invalidate(int)" (?Invalidate@CWnd@@QAEXH@Z)
        Referenced in AstraLink.lib(DrawMap.obj)
        Loaded mfc42d.lib(MFC42D.DLL)

It goes on obviously.  Oh the other 'third party' lib would be opengl, but it also is not the debug version.
0
 
jkrCommented:
>>The dependency walker has no profile option that I can see

Get the most recent version from http://www.dependencywalker.com
0
NEW Veeam Agent for Microsoft Windows

Backup and recover physical and cloud-based servers and workstations, as well as endpoint devices that belong to remote users. Avoid downtime and data loss quickly and easily for Windows-based physical or public cloud-based workloads!

 
Infiniti2000Author Commented:
I appreciate the pointer to the new depends.  In profiling, I see the first reference to the msvcrtd as listed below.  It seems that msvcrtd is being loaded by mfc42d, but I am unsure why mfc42d is being loaded.  I've looked through the tree and find no references in any of the DLLs.  I've searched the source code and similarly found nothing.  Any other pointers as to where I can go next would be greatly appreciated.

DllMain(0x10200000, DLL_PROCESS_ATTACH, 0x0012FD30) in "MSVCRTD.DLL" called by thread 1.
GetProcAddress(0x7C570000 [KERNEL32.DLL], "IsProcessorFeaturePresent") called from "MSVCRTD.DLL" at address 0x1024C0B9 and returned 0x7C597957 by thread 1.
DllMain(0x10200000, DLL_PROCESS_ATTACH, 0x0012FD30) in "MSVCRTD.DLL" returned 1 (0x1) by thread 1.
DllMain(0x5F400000, DLL_PROCESS_ATTACH, 0x0012FD30) in "MFC42D.DLL" called by thread 1.
LoadLibraryA("MSVCRTD.DLL") called from "MFC42D.DLL" at address 0x5F4998E9 by thread 1.
LoadLibraryA("MSVCRTD.DLL") returned 0x10200000 by thread 1.
LoadLibraryA("C:\WINNT\system32\MFC42LOC.DLL") called from "MFC42D.DLL" at address 0x5F499A72 by thread 1.
LoadLibraryA("C:\WINNT\system32\MFC42LOC.DLL") returned NULL by thread 1. Error: The specified module could not be found (126).
DllMain(0x5F400000, DLL_PROCESS_ATTACH, 0x0012FD30) in "MFC42D.DLL" returned 1 (0x1) by thread 1.
LoadLibraryA("ole32.dll") called from "MFC42.DLL" at address 0x6C3AD918 by thread 1.
LoadLibraryA("ole32.dll") returned 0x77A50000 by thread 1.
0
 
jkrCommented:
>>It seems that msvcrtd is being loaded by mfc42d, but I am unsure why mfc42d is being loaded

Hm, to find out about that, temporarily rename the DLL, e.g. (mfc42d.dl_), so you can track the load failure...
0
 
Infiniti2000Author Commented:
Interesting.  It provoked a "Cannot hook module" error for every module, like so:

Started "MYAPP.EXE" (process 0x554) at address 0x00400000 by thread 1.  Cannot hook module.
Loaded "NTDLL.DLL" at address 0x77F80000 by thread 1.  Cannot hook module.
...

Then it gave me this.

First chance exception 0xC0000135 (DLL Not Found) occurred in "NTDLL.DLL" at address 0x77FB17A4 by thread 1.
Second chance exception 0xC0000135 (DLL Not Found) occurred in "NTDLL.DLL" at address 0x77FB17A4 by thread 1.

0
 
jkrCommented:
Hmm - now try to link with /DELAYLOAD:mfc42d.dll and see if you can trap it in the debugger :o)
0
 
Infiniti2000Author Commented:
Odd, I've renamed it and put in delayload (no ready option so I typed it in the command line), and I got no errors when running the app or profiling it in the walker, but I still got the LNK4098 warning.  It still loads msvcrtd.dll, though, and I cannot use delayload on it (ignored via LNK4194 error), which is as I would expect.

I renamed msvcrtd.dll to msvcrtd.dl_ and got a similar error as above when I first renamed mfc42d.dll.
0
 
jkrCommented:
Hum, now it's getting a bit scary - can you set a breakpoint on e.g. '_malloc_dbg()' in msvcrtd.dll? (start the app in the debugger, navigate to the CRT\SRC directory in your VC++ installation and set it there)

This would at least allow to see which module calls functions in there...
0
 
Infiniti2000Author Commented:
Okay, doing that (after reenabling the DLLs) I get the following call stack:

_malloc_dbg(unsigned int 116, int 2, const char * 0x10256f04 `string', int 97) line 165
_calloc_dbg(unsigned int 1, unsigned int 116, int 2, const char * 0x10256f04 `string', int 97) line 506 + 21 bytes
_mtinit() line 98 + 18 bytes
_CRTDLL_INIT(void * 0x10200000, unsigned long 1, void * 0x0012fd30) line 200 + 5 bytes
NTDLL! 77f86215()
NTDLL! 77f86f17()
NTDLL! 77f8b845()
NTDLL! 77f8c295()
NTDLL! 77fa15d3()

_calloc_dbg is #defined from _calloc_crt only if _DEBUG is defined.  I've checked all the options and it is not defined in my app.
0
 
jkrCommented:
Hmm, this is only the DLL initialization - go a bit further into the execution...
0
 
Infiniti2000Author Commented:
Once it leaves _CRTDLL_INIT, _malloc_dbg is not called again.  I exercised most of the application.
0
 
jkrCommented:
<censored>
%$$/))!!!$
</censored>

This was the most promising export in that DLL. Well, any other function should do also, I just thought that this wane would be called really frequently...


0
 
Infiniti2000Author Commented:
I cannot seem to find one.  Any easy way to find one that would be called?  I've done searches on various CRT functions and put in breakpoints all over the place and ran the application, to no avail.  Maybe I'm just not doing it the right way, but it's not rocket science.  One other point, remember that this is Release mode, so maybe that affects where breakpoints can be set.

PS Thanks for all your help on this so far.
0
 
_nn_Commented:
What about doing a plain dumb file search ("msvcrtd" in *.* in the project folder and subfolders) ? That would possibly reveal some .obj (or .ilk ?) files referencing the debug version.
0
 
_nn_Commented:
Btw, did you apply the latest sp for VC++6 ?
0
 
Infiniti2000Author Commented:
Search: Did that.  Only the .MAP file had msvcrtd in it, as expected.

I have SP 5, which, according to the website, is the latest SP.
0
 
Infiniti2000Author Commented:
Sorry, I was not clear.  That is the debug .MAP file.  The .PLG file also had a reference to it, which was basically the LNK4098 warning message.
0
 
_nn_Commented:
/me is slowly feeling like jkr and wonders how mightily annoyed the asker can be...

Would you mind pasting the content of your .dsp file ?
0
 
Infiniti2000Author Commented:
If I am the asker, I am certainly not annoyed at the comments. :)
If I am annoying you guys, my apologies.

There are four .DSP's.  This is the main one, though not including all the source files, only one.

# Microsoft Developer Studio Project File - Name="MyApp" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **

# TARGTYPE "Win32 (x86) Application" 0x0101

CFG=MyApp - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "MyApp.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "MyApp.mak" CFG="MyApp - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "MyApp - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "MyApp - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE

# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe

!IF  "$(CFG)" == "MyApp - Win32 Release"

# PROP BASE Use_MFC 6
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 6
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /G6 /MD /W3 /GX /Ox /I "../NTDDK/inc" /I "./mil/include" /I "../MyLink" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
# SUBTRACT CPP /Fr
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
# ADD RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
# ADD LINK32 ..\MyGraphics\Release\MyGraphics.lib DelayImp.lib opengl32.lib glu32.lib ..\MyHardware\Release\MyHardware.lib ..\MyLink\debug\MyLink.lib ..\MyLink\lib\crush32.lib mil.lib milmet2.lib /nologo /subsystem:windows /incremental:yes /machine:I386 /libpath:"./mil/lib"
# SUBTRACT LINK32 /pdb:none /nodefaultlib

!ELSEIF  "$(CFG)" == "MyApp - Win32 Debug"

# PROP BASE Use_MFC 6
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 6
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /G6 /MDd /W3 /Gm /GX /ZI /Od /I "../NTDDK/inc" /I "./mil/include" /I "../MyLink" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_AFXDLL" /FR /Yu"stdafx.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 ..\MyGraphics\Debug\MyGraphics.lib DelayImp.lib opengl32.lib glu32.lib ..\MyHardware\Debug\MyHardware.lib ..\MyLink\Debug\MyLink.lib ..\MyLink\lib\crush32.lib mil.lib milmet2.lib /nologo /stack:0x989680 /subsystem:windows /map /debug /machine:I386 /pdbtype:sept /libpath:"./mil/lib"
# SUBTRACT LINK32 /pdb:none

!ENDIF

# Begin Target

# Name "MyApp - Win32 Release"
# Name "MyApp - Win32 Debug"
# Begin Group "Source Files"

# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File

SOURCE=.\MyApp.cpp
# End Source File
# Begin Source File

...
0
 
_nn_Commented:
!IF  "$(CFG)" == "MyApp - Win32 Release"

(...)

# ADD LINK32 (...) ..\MyLink\ »»» debug ««« \MyLink.lib (...)


I have a doubt here...
0
 
Infiniti2000Author Commented:
Ah ha!  That clearly must be it.  I will concentrate on looking at that particular spot.  It builds it in Release mode, but apparently links in the debug version.

Checking...

Yup!  After manually deleting the Debug library and object files, it fails to link.  Double checking the actual link line (scrolled off) and YES!  Changed it to Release...PROBLEM SOLVED!

Thanks!  jkr, thanks for your help, too, and I will give you both 500 pts.  jkr, please see a follow-up question for your points.
0

Featured Post

Prepare for your VMware VCP6-DCV exam.

Josh Coen and Jason Langer have prepared the latest edition of VCP study guide. Both authors have been working in the IT field for more than a decade, and both hold VMware certifications. This 163-page guide covers all 10 of the exam blueprint sections.

  • 11
  • 7
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now