origin

I shared an example of a DLL that failed to load due to the initialization sequence of global variables in my last article. If you are interested, you can click on it.

Although we know that the problem is caused by the initialization order of global variables, we also provide a solution. But there’s one thing that doesn’t really matter – why does changing the order of files in a project file change the order in which global variables are initialized? How does it affect you? This article tries to solve this problem.

Understanding VS compilation

We can easily divide the entire build process into three steps (there are actually other steps that we don’t care about) : precompile, compile, and link.

Precompilation: handles macros, #include expansion, etc.

Compilation: Generate the corresponding.obj file in units of compilation.

Link: Link the generated.obj files and necessary files into the final application.

guess

Because compiling puts symbols into the corresponding.obj file, linking links the corresponding.obj file into the final application. Links should place symbols in.obj in the order in which the.obj file appeared.

Train of thought

Compare and observe the compile parameters before and after the adjustment order, link parameters. Since the guess is that the link caused the problem, we will focus on the link parameters.

Preliminary Study on compilation Process

The entire process when we execute a build in VS is shown below (captured using Process Monitor) :

As you can clearly see, VS internally starts msbuild.exe for subsequent operations. Msbuild. exe will indirectly start cl.exe for compilation and link.exe for linking. We also found tracker.exe highlighted in yellow, a process used to speed up compilation. For details, please refer to the book Inside the Microsoft Build Engine Using MSBuild and Team Foundation Build.

Simplify the compilation process

Since VS uses msbuild.exe to perform operations, we can build directly using msbuild.exe. Msbuild has an option TrackFileAccess that can be used to control whether or not to use FileTracker. If the value is false, FileTracker is disabled.

To simplify things, we directly execute msbuild.exe -p:TrackFileAccess=false project_file_to_build.vcxproj.

We find that the arguments passed to cl.exe and Link.exe are files. Guess, the parameter should be saved to the file passed. It has been observed that these files are cleaned up after execution. You have to find a way to save a copy of these files before they are deleted. Do you have any ideas?

Let’s take a look at who created and deleted these parameter files and when they were deleted. It’s easy to create, it must be msbuild.exe. Delete? Cl.exe/link.exe or msbuild.exe? And when was it deleted? I believe the picture below can answer these questions well.

Two ideas come to mind:

  1. Because these files aremsbuild.exeCreated/deleted in themsbuild.exeAdd a breakpoint at the file operation in.
  2. You can pausecl.exe/link.exeCopy the files we need to the desktop.

The first idea is relatively complicated, and today we’ll try the second idea. How do we pause? Please the gflags. Exe.

Interrupt the link. Exe

We can set the following in gflags.exe, so that when link.exe starts, it will interrupt windbg.exe.

After breaking, we can type in WinDBG! The PEB observation parameter contains the path of the file we need to copy.

With the file path, we can manually copy the corresponding file to the desktop slowly study.

Comparison link parameter

Change the order of test1. CPP test2. CPP in.vcxproj and save the parameter files passed to link.exe as shown in the following figure:

Test1.obj test2. obj appears in a different order between the two links.

conclusion

Whichever source file appears first in.vcxproj will be processed first if the corresponding.obj file is earlier in the parameter file (.rsp) passed to link.exe. Global variables contained in.obj are processed first. When the process starts, global variable initializations are performed in sequence.

conclusion

  • vsWill be used internallymsbuild.exeCompile, we can also use it directlymsbuild.exeCompile.
  • usemsbuild.exe -p:TrackFileAccess=falseYou can do this without starting it during compilationTracker.exeWill help us investigate the problem.
  • We can interrupt the debugger when a process starts, which can be usedgflags.exeHelp us make that happen.
  • ! pebYou can view startup parameters, environment variables, and other information.
  • .vcxprojThe order of the files in the.

The resources

Inside the Microsoft Build Engine Using MSBuild and Team Foundation Build

Docs.microsoft.com/en-us/cpp/c…

www.cppblog.com/xlshcn/arch…