This article understands the role of the program database file .pdb (symbol file) during C# real-time debugging. Extend to understand the difference between Debug/Release, AnyCPU (32-bit preferred)/x86/x64/ARM

1. Preparation


MS References: Specifying Symbols (.pdb) and Source Files in Visual Studio Debuggers (C#, C++, Visual Basic, F#)

MS Reference: Generating Symbol Files for C#, ASP.NET or Visual Basic Projects (.NET Framework)

MS Reference: C# Compiler Options for Controlling Compiler Output


1. First, we need a console program. The code is very simple. The ConsoleApp1 console program is in the main program and calls the Do method under Class1 in the ClassLibrary1 class library, as follows:

2. Generate AnyCPU or any target platform, the directory structure of the code is as follows:

3. Then in the bin/Debug directory, double-click to run the console program. According to the code logic, the program stack will stop at the line "Console.ReadLine();";

4. ( Verify the usefulness of the normal debugging process.pdb ) Open VS, enter through "Continue without code", select "Debug" - "Attach to Process", enter the assembly name, find the process, and select "Attach";

 5. After the additional process is ok, click "All break" in debugging, and see that the breakpoint stays at the line "Console.ReadLine();":

2. How to remove .pdb

 6. To maintain the program state, what needs to be done is:

①Rename "..\ bin \Debug\ConsoleApp1.pdb" to "ConsoleApp1_Temp.pdb"

②Rename "..\ obj \Debug\ConsoleApp1.pdb" to "ConsoleApp1_Temp.pdb"

(The source .pdb file under obj is the source .pdb file, and the copy of the source .pdb file is in bin; the same is true for the exe under obj and bin; here you can learn about the compilation process, first generate the content under obj, and then copy the files needed at runtime to bin)

(When compiling, the path of .pdb will be recorded in the exe program, which is why ② should be done)

7. VS restarts the additional process, clicks "interrupt all", and the result of "in interrupt mode" will be obtained, but due to the lack of .pdb, the tool stack cannot be located:

 3. How to remove native code

7. Keep the program state, restore what you did in step 6, rename the .pdb under obj and bin, and then you need to do:

① Rename the source code file "Program.cs" to "Program_Temp.cs"

8. VS restarts the additional process, clicks "Stop All", and you will get the result of "No source found". You can see the content in the "Local Variables" and "Call Stack" tabs, but there is no corresponding source code location:

 Four. Summary

        First, why choose to attach to a process instead of launching with the "Active Solution Platform Configuration" set to "Debug" in the project? ——Every time the Debug mode is started, the source.pdb under obj will be generated by default and copied to the bin output directory.

        Secondly, the above steps are for the scenario of " using .pdb plus source code for debugging in the production environment ". (Some people will say that the Release version should be placed in the production environment, and there will be no .pdb. Then look down, the actual reason is that the breakpoint cannot be hit accurately because the code is optimized when the Release is generated by default, and pdb is not selected to be compiled under "Generation" - "Advanced Settings") .

        Finally, .pdb records debugging information, which needs to correspond to the source code. When debugging in real time, you need to copy the .pdb and single or multiple source code files to be debugged to the target machine in the production environment. After selecting the additional process, exe or dll will be used as the module, and pdb will be used as the symbol of the module ("debug"-"window"-"module"-right-click "exe or dll" module name-select the .pdb path), and the source code will be used as the debugging source file ("Solution Explorer"-right-click "Solution 'Solution1' (0 projects)"-"Properties"-"Debugging Source Files"-add .cs folder), you can jump to the code line after hitting the breakpoint .

        See the reference for specific operations: What is a PDB file? Detailed explanation of PDB file format


Five, expansion - the difference between Debug and Release

Five-one, normal debugging Release

1. Right-click the "ConsoleApp1" project - "Properties" - "Generate" - "Advanced";

2. By default, when the "configuration" is set to Debug and Release, the difference we can see is the " optimized encoding " item. When debugging, the default is "not selected", that is, "not optimized encoding"; when it is released, the default "selected" is "optimized encoding".

3. At this time, follow the above process to debug the exe under Release, you will be prompted, and choose "Continue Debugging":

 4. Clicking "Break All" will not hit the line "Console.ReadLine();" of the current stack, and there is no content in the "Local Variables" and "Call Stack" tabs.

 Five-two, cancel the "optimized coding" debugging Release

        No more textures, just release the result, just like we debug Debug .

5-3. Conclusion

        When debugging with VS, the main difference between Debug and Release is whether "optimized coding" has been carried out (in fact, even if the configurations are completely consistent, comparing the hexadecimal system will still show that the two are not the same, such as generating timestamps and code segment addresses).

        As for the result of optimization, my personal understanding is:

Is it possible to attach to the process and "accurately" hit breakpoints in a normal production environment through .pdb and source code (some breakpoints after optimized coding can also be hit)

 

6. Expansion - the difference between AnyCPU (32-bit preferred)/x86/x64/ARM

(The original text of MS is quoted below)        

PlatformTarget

Specifies which version of the CLR can run the assembly.

XML copy

<PlatformTarget>anycpu</PlatformTarget>
  • anycpu (the default) compiles the assembly to run on any platform. Your application will run as a 64-bit process whenever possible; it will fall back to 32-bit when only 32-bit mode is available.
  • anycpu32bitpreferred compiles the assembly to run on any platform. On systems that support both 64-bit and 32-bit applications, your application will run in 32-bit mode. This option can only be specified for projects targeting .NET Framework 4.5 or later.
  • ARM compiles assemblies to run on computers with Advanced RISC Computer (ARM) processors.
  • ARM64 Compiles assemblies to run on computers with Advanced RISC Computer (ARM) processors that support the A64 instruction set by the 64-bit CLR.
  • x64 compiles the assembly to be run by the 64-bit CLR on computers that support the AMD64 or EM64T instruction set.
  • x86 compiles assemblies to be run by the 32-bit, x86-compatible CLR.
  • Itanium compiles assemblies to be run by the 64-bit CLR on computers equipped with Itanium processors.

On 64-bit Windows operating systems:

  • Assembly compiled for x86 will execute on the 32-bit CLR running under WOW64.
  • A DLL compiled with anycpu will execute on the same CLR as the process that loaded it.
  • Executables compiled with anycpu will execute on the 64-bit CLR.
  • Executables compiled with anycpu32bitpreferred will execute on the 32-bit CLR.

The anycpu32bitpreferred setting is only valid for executables (.EXE) and requires .NET Framework 4.5 or later. 

Guess you like

Origin blog.csdn.net/qq_23958061/article/details/130223918