Debugging .NET in Docker: Mount Points and Cross-platform Symbols

Pavel OsadchukPavel Osadchuk
3 min read

Today I want to share a tricky debugging issue I encountered with Visual Studio's Docker tools and how I fixed it. The problem arose when trying to debug a .NET application that uses a custom base image with pre-installed Python.

The Problem

My application Docker is based on a custom Docker image that comes with Python pre-installed at /app/python. This is a requirement I cannot change, and Python must be available at this specific location for the application to work.

# This stage is used when running from VS in fast mode (Default for Debug configuration)
FROM myregistry.azurecr.io/base-python:latest AS base
USER $APP_UID
ENV Python3_ROOT_DIR="/app/python"
WORKDIR /app
EXPOSE 8080
EXPOSE 8081

When trying to debug the application from Visual Studio using Fast Mode (default for Debug configuration), I ran into a problem.

💡
Visual Studio's Fast Mode is designed to speed up the development cycle by building on host system and mounting the build output directly into the container instead of copying files during image build.

The issue was that Fast Mode was mounting my application files to /app (the WORKDIR), which effectively overlaid and hid the Python installation that was already there. As a result, Python became unavailable and the application couldn't work properly.

Issue 1: Fixing the Mount Points

After some research, I found that Visual Studio's mounting behavior can be controlled through the project file. The solution was to configure Fast Mode to mount files into a different directory:

<PropertyGroup>
    <DockerDebuggeeWorkingDirectory>/app/dotnet</DockerDebuggeeWorkingDirectory> 
    <DockerFastModeProjectMountDirectory>/app/dotnet</DockerFastModeProjectMountDirectory>
</PropertyGroup>

This configuration tells Fast Mode to:

  1. Mount application files to app/dotnet instead of /app

  2. Set the working directory for the debugger

  3. Leave the Python installation at /app/python intact and accessible

Issue 2: Windows PDBs Not Working

After fixing the mount point, I encountered another issue. When trying to hit breakpoints, the debugger was complaining about symbol files:

WARNING: Could not load symbols for 'MyCompany.Service.dll'. 
'/src/build/bin/.../MyCompany.Service.pdb' is a Windows PDB. 
These are not supported by the cross-platform .NET Core debugger.

The problem comes from the difference between debugging environments. While developing on Windows, Visual Studio by default generates Windows PDB files (Program Database) which contain debugging information. However, when debugging in a Linux container with the cross-platform .NET debugger, these Windows-specific PDBs aren't supported.

Microsoft introduced Portable PDBs exactly for this cross-platform scenario - they contain the same debugging information but in a format that works across different operating systems. The solution was to tell the compiler to generate portable PDBs instead of Windows ones:

<PropertyGroup>
    <DebugType>portable</DebugType>
</PropertyGroup>

After this change and rebuilding the application, the debugger successfully loaded the symbols and I could debug my application running in the container.

References

That's it. Both issues fixed and debugging now works as expected.

0
Subscribe to my newsletter

Read articles from Pavel Osadchuk directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Pavel Osadchuk
Pavel Osadchuk

I'm a .NET Developer working on MS Stack for more than 12 years already. I worked with most dotnet-based technologies, from WinForms to Azure Functions. In my time, I won a dozen hackathons, launched a couple of startups, failed them, and am now working as a lead .NET developer in an enterprise company.