Solved

Yet Another LNK4098

Posted on 2003-10-29
22
2,222 Views
Last Modified: 2013-12-03
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
Comment
Question by:Infiniti2000
  • 11
  • 7
  • 4
22 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 9644200
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
 
LVL 1

Author Comment

by:Infiniti2000
ID: 9644303
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
 
LVL 86

Expert Comment

by:jkr
ID: 9644348
>>The dependency walker has no profile option that I can see

Get the most recent version from http://www.dependencywalker.com
0
 
LVL 1

Author Comment

by:Infiniti2000
ID: 9644694
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
 
LVL 86

Expert Comment

by:jkr
ID: 9644715
>>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
 
LVL 1

Author Comment

by:Infiniti2000
ID: 9644863
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
 
LVL 86

Expert Comment

by:jkr
ID: 9644941
Hmm - now try to link with /DELAYLOAD:mfc42d.dll and see if you can trap it in the debugger :o)
0
 
LVL 1

Author Comment

by:Infiniti2000
ID: 9645269
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
 
LVL 86

Expert Comment

by:jkr
ID: 9645453
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
 
LVL 1

Author Comment

by:Infiniti2000
ID: 9645715
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
 
LVL 86

Expert Comment

by:jkr
ID: 9645783
Hmm, this is only the DLL initialization - go a bit further into the execution...
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 1

Author Comment

by:Infiniti2000
ID: 9645911
Once it leaves _CRTDLL_INIT, _malloc_dbg is not called again.  I exercised most of the application.
0
 
LVL 86

Expert Comment

by:jkr
ID: 9645933
<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
 
LVL 1

Author Comment

by:Infiniti2000
ID: 9646050
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
 
LVL 16

Expert Comment

by:_nn_
ID: 9646429
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
 
LVL 16

Expert Comment

by:_nn_
ID: 9646464
Btw, did you apply the latest sp for VC++6 ?
0
 
LVL 1

Author Comment

by:Infiniti2000
ID: 9650159
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
 
LVL 1

Author Comment

by:Infiniti2000
ID: 9650361
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
 
LVL 16

Expert Comment

by:_nn_
ID: 9650569
/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
 
LVL 1

Author Comment

by:Infiniti2000
ID: 9650749
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
 
LVL 16

Accepted Solution

by:
_nn_ earned 500 total points
ID: 9651060
!IF  "$(CFG)" == "MyApp - Win32 Release"

(...)

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


I have a doubt here...
0
 
LVL 1

Author Comment

by:Infiniti2000
ID: 9651158
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

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

This tutorial is about how to put some of your C++ program's functionality into a standard DLL, and how to make working with the EXE and the DLL simple and seamless.   We'll be using Microsoft Visual Studio 2008 and we will cut out the noise; that i…
This article shows a few slightly more advanced techniques for Windows 7 gadget programming, including how to save and restore user settings for your gadget and how to populate the "details" panel that is displayed in the Windows 7 gadget gallery.  …
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now