質問

I'm trying to get a stack-trace information at runtime.

I'm using following code, and this works fine in the default project configuration:

  StackTrace trace = new System.Diagnostics.StackTrace(true);
  StackFrame frame = trace.GetFrame(0);
  int line = frame.GetFileLineNumber();
  Console.WriteLine(line);

However, the solution I'm trying to build is configured to put binaries and PDBs to separate folders:

<PropertyGroup>
  ...
  <OutputPath>Binaries\$(Configuration)\bin\</OutputPath>
  <IntermediateOutputPath>Binaries\$(Configuration)\obj\$(MSBuildProjectName)\</IntermediateOutputPath>
  <PdbFile>Binaries\$(Configuration)\pdb\$(MSBuildProjectName).pdb</PdbFile>
  <SkipCopyingSymbolsToOutputDirectory>true</SkipCopyingSymbolsToOutputDirectory>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
  <PlatformTarget>AnyCPU</PlatformTarget>
  <DebugSymbols>true</DebugSymbols>
  <DebugType>full</DebugType>
  <Optimize>false</Optimize>
  <DefineConstants>DEBUG;TRACE</DefineConstants>
  <ErrorReport>prompt</ErrorReport>
  <WarningLevel>4</WarningLevel>
</PropertyGroup>

I can see in Modules window in Visual Studio that PDB was loaded. However, the frame variable doesn't contain information about source file (filename, line and column). If I copy .pdb and .exe to the same folder, output is correct again.

Therefore, as far as I understand:

  • PDB is correct (contains necessary information), because it works when I put files to the same folder
  • Visual studio is able to load the PDB, so the search path should also be correct

I have searched the internet (including http://msdn.microsoft.com/en-us/library/ee416588.aspx and Display lines number in Stack Trace for .NET assembly in Release mode), but all article mostly focus on loading PDBs from correct location (and as far as I'm concerned, that's not the case). What I do not understand is why the source-file/line information is not be obtained, although PDB is loaded.

So, the question is: is it possible to get Stack Trace containing information about source-files, when .pdb was loaded from different location? If not, why?

役に立ちましたか?

解決

You are just giving the CLR a hard time to locate the PDBs. The info you see in the debugger's Modules window is not relevant, that only matters for the debugger. The CLR has its own mechanism to locate and read PDBs. Necessarily so, this still needs to work without a debugger on the user's machine.

It is technically possible to tell the CLR where to look by setting an environment variable. Say you stored the PDB files in a subdirectory named "pdbs" then you could put this code in your Main() method:

var appdir = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
var pdbdir = System.IO.Path.Combine(appdir, "pdbs");
Environment.SetEnvironmentVariable("_NT_SYMBOL_PATH", pdbdir);

Or just don't give it a hard time and put them in the same directory as your EXE.

他のヒント

is it possible to get Stack Trace containing information about source-files, when .pdb was loaded from different location?

Yes but you need to tell Visual Studio where that location is, if it is not within the current directory. Specify the location in Tools->Options->Symbols in VS by adding the location of alternate PDB folder.

See the section entitled Specify symbol locations and loading behavior in Specify Symbol (.pdb) and Source Files in the Visual Studio Debugger for more information.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top