How to find an application's entry point in Visual Studio (C++) - c++

The question may apply to any programming language written in Visual Studio, but I am more concerned about C++.
Is there a way to easily determine the application entry point in Visual Studio?
For a relatively small application this could be easy, but for large ones, it will be pretty hard. In my particular case I know that the project which is set as startup is the one which has the entry point, but I was unable to find it, even though the application starts and runs well.

If you want to find what C++ project is executable than search for <ConfigurationType>Application</ConfigurationType> in all your *.vcxproj files.
If you are looking for the entry point function inside this application, than search for main, wmain or WinMain functions.
Also entry point can be redefined with /ENTRY parameter, so you can check Configuration Properties > Linker > Advanced > Entry Point project parameter or search for /ENTRY in your *.vcxproj.

In C++, a fully compiled program can have only one defined main method. If there's more than one, the compiler will complain about "multiple definitions of main" or some other similarly worded message.
So, the simplest option is to do a search for the symbol main (or, if compiling as a Windows Subsystem program, WinMain) and figure out which ones correspond to the "startup" project. There shouldn't be that many, even in a relatively large solution.

When desiring to stop execution at the top of the main/WinMain function while interactively debugging a process on Windows, I typically just use F10/F11 (assuming default C/C++ key bindings in the Visual Studio IDE) to instruct the debugger to single-step (which starts the process, then performs the step, then breaks).
Note this may not always do what you want. If you want to catch global initializations, object constructions, etc, these are already done before reaching main or WinMain. Those require additional debugging and setting breakpoints in CRT-source code for the real global startup code (which eventually calls your main or WinMain). But if you simply want to break-on-main-entry for a program built with debugging symbols, this is likely the easiest way to do it.

Related

Windows C++ MFC migration: AfxGetThread Assertion. Why does win32u.dll load before mfc140d.dll in some cases?

I have customer code written for Visual Studio 6.0 MFC which has a simple GUI and launches an EXE with arguments. This code was ported from VS6.0 to VS2019 about 2 years ago and works in a production environment on several systems. We now have a new system where the code fails to function... and I'm starting to dig.
The code is throwing exception in appcore.cpp line 196
It is crashing at AfxGetThread() now that I have been able to get VS2019 to find "appcore.cpp".
This is new information.. I will be searching on AfxGetThread next... so this question likely to be a duplicate now.
One difference I have detected is the order where the Visual Studio 2019 debuger loads symbols. I can't say for certain that this is an indication of the actual DLL load order at runtime, but it appears to be. The screenshot below is the SYMBOL load order where a difference is detected between the working and non working instance of the application.
In the image below we have a Tortoise SVN Diff of two ASCII files. One is the DLL symbol load order on the left when the application works. The second is the DLL symbol load order on the right when the application fails to work. Line 7 is the divergance, where in the failig case the library win32u.dll is pulled in before mfc140d.dll.
The customer code uses some Apache log4cxx libraries which I need to investigate, but at this point in the load sequence I'm not 100% sure differences in those libraries or *.h files used at build time could influence the DLL loading order.
So this is the puzzle I'm looking at.
I will include some links to relevant StackOverflow questions that are similar in my search for an answer to this question.
Possibly Useful Links:
https://learn.microsoft.com/en-us/cpp/porting/porting-guide-mfc-scribble?view=msvc-170
The DLLs are searched in order in different locations: Standard Search Order for Desktop Applications
Most likely the DLLs on the failing machine are missing or they are in the wrong location, so Windows grabs something else.
Make sure all the dependencies are installed in the correct folders.
In this case, the crash in appcore.cpp was due to the code having 2 CWinApp derived objects in the code. And the crash occurs at construction time.
The first hurdle is to get VisualStudio2019 to find appcore.cpp and be able to step into this code. I browsed to C:\Program Files(x86)\VisualStudio and searched for "appcore.cpp". This provided the trail of breadcrumbs to get Visual Studio2019 the correct path when it asked for the file.
In my case the path is:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30037\atlmfc\src\appcore.cpp
The second hurdle was to put a breakpoint at the ASSERT point, as the FIRST time the program comes up, this ASSERT is OK. At least in my case... the first constructor of the CWinApp object succeeded. So in my case the offensive code which was unexpectadly constructing a CWinApp derived object ran first. Then the second iteration through the ASSERT would happen.
By placing a breakpoint at the ASSERT, you can re-launch and look at the stack trace of the successful object to determine if it's expected or not.
In my case there was a *.h fix required to get ancient Visual Studio 6.0 MFC code to build and link successfully. I don't have the exact secret, but it's essentially getting a *.h to specify the proper WIN_VER minimum windows version before afx.h is included. For the code that failed, an incorrect *.h was included that included the fix PLUS objects that derived CWinApp.
As near as I can tell, the reason this worked on some sites and not others was due to a regression in the code that was built on that particular system.
The other "strange" behavior was that on the system with the bad *.h include the DLL symbol load order was different. I was able to replicate this bad behavior on more than one system running the "bad" Exe code. Then I did the same on working *.exe code. The strange thing was that the "bad" exe had reasonably correct sources in the workspace. So there were source control issues leading to this belief that it worked on one node and not others.
The runtime behavior I was able to catch matched obsolete code committed to source control.

How to debug program crashing before main()

I'm using QtCreator with the visual studio 2015 kit on windows 8.1 to build a program I developed and tested on Linux, on linux it works correctly, but on windows it's just crashing immediately, and I have no idea what to look for.
The only external libraries, aside from QT I'm using are opengl and glew, so I don't think it's those.
Is there anything that's known to work in GNU C++ but crash immediately in MSVC?
Usually this kind of crashes have absolutely nothing to do with your program. It's an external library linking issue. I had this issue recently with the OpenSplice DDS library. I linked to a library that caused a segmentation fault before anything started. I resolved the issue by linking the pre-compiled libraries 1-by-1, and check each if that fixes the program.
What I recommend you to do is: Remove the libraries and resources you're linking to gradually, until your program starts and prints "Hello world" from the first line of main().
Another way to go is, make a new empty program, and link the same resources you're using in your program. This is easier, as it doesn't involve modifying your program.
This is what I would do.
Start by rebuilding the entire solution or project from a clean state. Just in case this is just some weird dependency issue that resulted in something not getting recompiled. Never hurts.
As Neil said in the comments for the question, the crash is possibly coming from a global variable who's constructor runs before main or WinMain. Are you sure you don't have something declared as "static" or at global scope that might have a constructor?
Now do the following:
Open Visual Studio.
From the menu, select File->Open->Project/Solution...
When the file open dialog pops up, select the EXE produced by Qt
Creator. (That's right - you are opening the EXE as a project). This directory is typically one folder level above the Qt project (..\build-yourapp-Desktop_Qt_5_7_0_MSVC2015_32bit-Debug\debug)
Now press the green arrow to start debugging (menu->Debug->Start
Debugging). If all goes well, your program will fail early and
Now chances are high that the program is not going to run at all under Visual Studio because Qt Creator doesn't copy all the Qt*.dll binaries to your build directory. You'll get a bunch of dialogs popping up saying that "The program can't start because Qt5-XYZ.dll can't be found". This is easily fixed by updating your PATH environment in any of the following way to include your Qt5.x.0\5.x\msvc2015\bin folder to your PATH.
You add it from the command linke and then re-launch devenv.exe from the command line.
You can add it globally from Control Panel->System->Advanced. Then restart Visual Studio from the Windows desktop.
With the EXE debug project open from within Visual Studio, just right click on the project name (not parent solution) and a dialog will popup that allows you to edit startup settings. One of which is the Environment.
And that should do it. From there you can start the debugger on your EXE, set breakpoints as needed, and analyze the call stack on crash.
It's really easy: build all the libraries you use, including Qt, with debug information (those can be release builds as long as the PDB files are generated). Then run your application under a debugger (e.g. F5 under Qt Creator), and it will stop at the point of the crash.
The code that runs before main and is known to cause trouble will be the global object initialization: you're likely running into the static initialization order fiasco.
Another cause for the problem could be stackoverflow. In Linux, the stack size by default is usually 8 MB whereas in Windows it's just 1 MB.
Try to link with /STACK:8388608 switch. If it works, you might consider allocating more data on the heap and stay with the default stack size of 1 MB.

VS C++ 2010 debugging with external entry point

I'm creating Win32 application and I have two projects.
The first one is a static library which contains _tWinMain() function, that is the entry point of a Win32 application.
The other one is an application which links this .lib. That way, the app doesn't have to create its own _tWinMain() function, because it's in the .lib file.
First, I build the static library. Then I build the application. The problem is that when I start debugging (F5), the window shows and then immediately closes (either in Debug or Release configuration). The problem doesn't occur when I start the program without debugging (Ctrl+F5) or just open the .exe file.
Is it possible to debug while having the entry point in a static library?
I think it should be possible. Did you try what happens when you start the application with F11 or F10 instead of F5? It will then start the application, but breaks directly at WinMain.
SOLVED:
I had a small bug in one of my functions (always remember to initialize variables ;) ). _tWinMain() quited because of that. Now everything works fine, with the entry point in static library as described above. Thanks everyone for help and sorry for bothering you :)

Program crashes when outside test environment - C++

I have a program that runs fantastically when run from inside Visual Studio 2010 Express but when built and taken out, it has problems. I have set up the external test environment the same as when it is run from within Visual Studio so that shouldn't be the problem. I want to attach it to the .exe to see where the crash is but I don't have the non-Express versions.
Any suggestions? Why would a program crash outside of the the VSC++ 2010 Express environment but run perfectly inside.
I would post code but it's a huge project, not a line that would cause an error.
Thank you so much for your time.
It's very difficult to know for certain without knowing what the crash is, but a couple of common issues that may cause this:
Environment variables not the same. Perhaps you are relying on something in vcvars32.bat in your test environment.
The PATH environment variable is not the same and your picking up some bad or incompatible DLL.
Your code is somehow dependant on the current working directory being the one when run from Visual Studio.
Wikipedia to the rescue?
Time can also be a factor in heisenbugs. Executing a program under control of a debugger can change the execution timing of the program as compared to normal execution. Time-sensitive bugs such as race conditions may not reproduce when the program is slowed down by single-stepping source lines in the debugger. This is particularly true when the behavior involves interaction with an entity not under the control of a debugger, such as when debugging network packet processing between two machines and only one is under debugger control.
Also, note that User32.dll slightly changes its behavior when under a debugger, in order to make debugging easier for you. That shouldn't change anything, though.
You could debug this using the freely available Debugger Tools for Windows. There's plenty of documentation and quick start guides available, especially the chm included in the install. In your case, you may want to try the following:
Make sure you have the PDBs for your app available somewhere on a share.
Attach to the running instance of the app: windbg -p <PID>. Note that you can also start the program under the context of the debugger by doing windbg -g foo.exe.
Repro the crash.
Change the symbol path to your symbols and the Microsoft public symbol server to get proper symbols for components: .sympath x:\YourPathToPDBs; SRV*x:\symbols*http://msdl.microsoft.com/download/symbols
Tell the debugger to reload symbols using your path: .reload
Get a callstack by hitting k in the debugger.
That's the barebones you need to figure out where it's crashing. You can then go deeper and try to analyze exactly why it's crashing by looking at the debugger chm or other resources on MSDN or Tess's blog. One useful command is dv to dump local variables for a particular frame. If the callstack doesn't give line numbers, type .lines and then hit k or kb.
You could surround all code in your Main function with a try catch block. When you catch an excepcion, write to a log file the stack trace.
Then run your exe and check the log file to know where your program is crashing.
PS: Don't forget to place the *.pdb file together with the exe file, otherwise you won't be able to get the stacktrace information.
I realise this question is a couple of years old, but I have been experiencing the same thing and came upon a possible culprit (the actual culprit in my case), which may help others who have this issue.
One important difference when running an application within Visual Studio and running it outside is the Current Working Directory ("CWD").
A typical directory structure for a Visual C++ Solution/Project is along these lines:
Solution <- the location of your solution file
Debug <- where the Debug executables end up
Release <- where the Release executables end up
Project <- the location of your project file
Debug <- where Debug intermediate files end up
Release <- where Release intermediate files end up
When you execute the application from within Studio, either with "Start Debugging" or "Start Without Debugging", the default CWD is the Project directory, so in this case Solution\Project.
However, when you execute outside by simply double-clicking the application, the CWD is the application directory (Solution\Debug for example).
If you are attempting to open a file from the current directory (which is what happens when you do std::ifstream ifstr("myfile.txt")), whether it succeeds depends on where you were when you started the application.

What's the use of .map files the linker produces?

What is the use of .map files VC++ linker produces when /MAP parameter or "Generate map file" project setting is used? When do I need them and how do I benefit from them?
A nice article on how to use map files for finding crashes.
http://www.codeproject.com/KB/debug/mapfile.aspx
Manually doing all this is very uninteresting.
I am not aware of any tools which can read map file and help in finding the crash location. If anybody knows please update us.
For embedded systems, map files are a lot more useful. (Although you wouldn't be using Visual C++ for that ;)
Things like knowing how close you are to running out of program/data memory, and what location a particular variable resides in, are important.
WinDBG uses .map and .pdb files to help debug crashes, when analysing .hdmp and .mdmp crash dumps.
Basically they map memory address offsets to functions and variables within the .exe (and/or loaded .dlls). Very useful in general if you need to figure out why a customer is upset. Even more useful when they prove it was not your fault.
The most useful way to debug "post-mortem" crashes is using WinDbg (Windows platform). Open it up, and open the crash dump. Then set the source path to point at the code (if you have it), the symbol path to point at your .map and .pdb and the image path to the .exe, and type "!analyse -v" in the command line. Now you have a full stack trace with lines of code and everything. Of course you need to have the correct version of the source code for the version of the exe's and DLLs you are debugging.
It's even better if you have the MS symbol server in the path, and if the full page heap was turned on or adplus was running. With ADPlus in particular you will likely have variable values captured as well.
Some favourite WinDbg resources of mine:
First stop :: http://www.microsoft.com/whdc/devtools/debugging/debugstart.mspx
Force load the symbols :: http://www.osronline.com/ShowThread.cfm?link=182377
Useful site :: http://www.dumpanalysis.org/blog/index.php/category/windbg-tips-and-tricks/page/7/
You need them rarely, but they can be handy debugging some problems because they give information on the location of functions and data.
For example:
detailed information on all segments (code, data and other).
link line numbers to code
You can use map files for debugging tools.
Linker maps can be very useful in large projects when you need to track dependencies between compilation units and libraries. Typically, a linker will report a symbol which caused problems, and more often than not, a simple search for this symbol name won't return any results (or will return tons of false positives for symbols like read).
Without a linker map, the only option you have is to analyze all available source files (after preprocessing pass if macros were used, which is typically the case) and hope that you find the relevant spot.
Linker maps usually have a section called "reference by file/symbol" which tells you which object file was required by another object file of your project, and which symbol exactly was referenced.
I was once working on a project which had to be ported on a system without locale support. The linker was reporting "undefined reference to _localeconv_r" errors, which would have been a pain to track down by searching through the sources. Luckily, a GCC linker map file generated with -Map=output.map revealed all problematic functions with a single search.
amap cross-platform GUI tool allows you to examine MAP files produced by the GCC, Visual Studio and some other compilers. You can find out, for example, how much every source file and every external dependency contribute to size of your executable.