Depurar un bug que solo ocurre en una máquina sin Visual Studio

Un bug se reproduce en el servidor de pruebas y no en tu portátil. El servidor de pruebas no tiene Visual Studio, e instalar un IDE completo ahí solo para poner un breakpoint no es una opción. La depuración remota está pensada exactamente para esto. Un programa standalone pequeño corre en la máquina destino, tu Visual Studio local se conecta a él por red, y obtienes breakpoints e inspección de variables sobre un proceso que no está corriendo cerca de tu escritorio.

Hay tres pasos: ejecutar el depurador remoto en el destino, conectar desde Visual Studio, cargar los símbolos correctos. Cada uno falla de una forma propia y específica. Después de esos vienen los dos destinos remotos con los que más te vas a topar en la práctica: un proceso dentro de un contenedor Docker y una app en Azure App Service.

Cómo instalar y ejecutar el depurador remoto de Visual Studio (msvsmon)

El programa es msvsmon.exe, el Visual Studio Remote Debugger. Puedes ponerlo en la máquina destino de dos formas.

Si el destino ya tiene instalado Visual Studio Community, Professional o Enterprise, msvsmon.exe ya está ahí, en <carpeta de instalación de Visual Studio>\Common7\IDE\Remote Debugger\x64\ (o x86\, según la arquitectura que estés depurando). Ejecútalo directamente.

Si no, descarga el paquete standalone de herramientas remotas desde la página de remote tools de Microsoft para tu versión de Visual Studio, y toma su última actualización. La compatibilidad solo funciona en un sentido: herramientas remotas más nuevas funcionan con un Visual Studio más antiguo, pero herramientas remotas antiguas pueden rechazar uno más nuevo. Elige la arquitectura del sistema operativo destino (x86, x64 o ARM64), no la de la app que estás depurando.

El primer arranque abre un asistente de configuración que añade una regla de Windows Firewall para el tipo de red en la que estás (dominio, privada o pública). Al terminar, la ventana del Remote Debugger muestra un nombre de servidor y un puerto. Esa es la dirección que vas a escribir en Visual Studio. Deja la ventana abierta: cerrarla (File > Exit) termina la sesión.

Puertos y autenticación del depurador remoto: qué bloquea la conexión

La regla de firewall que crea el asistente solo abre el puerto TCP entrante, y ese puerto cambia según la versión de Visual Studio. Es el 4026 para Visual Studio 2022; versiones anteriores usan otros números. Si el destino está detrás de un firewall que el asistente no configuró, como un appliance corporativo o un grupo de seguridad en la nube, abre tú mismo ese puerto concreto. Adivinar “el puerto del depurador” sin comprobar tu versión hace perder tiempo.

UDP 3702 saliente es opcional. Permite que el destino aparezca en el selector Find de Visual Studio. Sin él igualmente puedes conectar; escribes la dirección a mano.

El modo de autenticación tiene que coincidir en ambos extremos. Por defecto el depurador remoto usa Windows Authentication, así que la cuenta de Windows que ejecuta Visual Studio necesita permiso en el depurador remoto. Concédelo desde Tools > Permissions en la ventana del Remote Debugger (requiere derechos de administrador), o arranca msvsmon desde línea de comandos con la cuenta ya autorizada:

1
msvsmon /allow user@computer

Cambiar a No Authentication (Tools > Options en la ventana del Remote Debugger) se salta todo eso, y en una VM desechable resulta tentador. Hazlo solo en una red en la que confíes por completo. Cualquiera que pueda llegar a ese puerto puede conectarse a cualquier proceso que corra bajo la misma cuenta: sin prompt, sin contraseña.

Cómo conectar a un proceso remoto desde Visual Studio

Con el depurador remoto corriendo y accesible:

  1. En Visual Studio, abre Debug > Attach to Process (Ctrl+Alt+P).
  2. Pon Connection type en Remote (Windows).
  3. En Connection target, escribe la dirección en el formato que muestra la propia ventana del depurador remoto, normalmente <nombre-de-máquina>:<puerto>. Si el nombre de la máquina no resuelve, usa la IP: 10.0.0.15:4026.
  4. Pulsa Refresh para traer la lista de procesos de la máquina remota, y busca y selecciona tu proceso. Si no corre bajo tu cuenta, marca Show processes from all users. Visual Studio muestra un aviso de seguridad antes de conectarte a un proceso que pertenece a otra persona; léelo en vez de descartarlo.
  5. Deja Code type en Automatic. La excepción es un proceso de código mixto donde el attach falla en silencio para un lenguaje: elige ese lenguaje explícitamente y vuelve a conectar, y obtienes un error concreto en vez de nada.
  6. Pulsa Attach.

Para una app ASP.NET alojada en IIS, el proceso que buscas es w3wp.exe. Para una app .NET con su propio servidor Kestrel, es dotnet.exe o el nombre del ejecutable de la propia app. IIS suele correr varios w3wp.exe idénticos uno al lado del otro. La columna Command Line en la lista de procesos es lo que los distingue.

Cómo arreglar “no symbols loaded” en depuración remota

Conectar no significa que ya puedas depurar. Abre Debug > Windows > Modules y mira la columna Symbol Status de tu binario. Un círculo de breakpoint rojo hueco en vez de uno sólido dice lo mismo desde el editor: el depurador no tiene símbolos con los que mapear ese breakpoint.

Tres estados aparecen en la práctica:

EstadoQué significaSolución
Skipped loading symbolsLa carga de símbolos está filtrada por tu configuraciónRevisa Debug > Options > Symbols por si hay una regla de inclusión/exclusión bloqueando este módulo
Cannot find or open the PDB fileNo hay ningún .pdb que coincida accesibleCopia el .pdb exacto del build que produjo el binario desplegado a la máquina remota, o apunta Visual Studio hacia él
Sin entrada / solo hex con pinta nativaEl módulo no tiene información de depuraciónSe compiló en Release sin .pdb, o es una DLL del sistema que no necesitas depurar

La mayor parte del tiempo perdido aquí viene de una sola regla: el depurador solo acepta un .pdb que coincida exactamente con el binario. No “la misma versión”. El archivo de ese build concreto. Si la máquina remota se redesplegó después de tu último build local, tu .pdb local ya no coincide. Cuando la carga automática no lo encuentra, haz clic derecho en el módulo dentro de la ventana Modules, elige Load Symbols, y navega hasta la propia carpeta de salida del despliegue.

El hábito que evita todo esto: despliega siempre el .pdb junto al binario en cualquier despliegue que puedas necesitar depurar. Reconstruir uno que coincida después de los hechos casi nunca funciona.

Cómo depurar un proceso dentro de un contenedor Docker

Todo lo anterior asume una máquina Windows en la que puedes instalar software. Un contenedor es distinto. No metes msvsmon en una imagen de producción, y dependiendo de la configuración de la red Docker, puede que el contenedor ni siquiera sea alcanzable por nombre desde tu host.

Si el proyecto tiene el soporte de Docker activado (Add > Docker Support, o un proyecto ya generado con un Dockerfile), las herramientas de contenedores de Visual Studio hacen el trabajo: F5 construye una imagen configurada para depuración, arranca el contenedor y conecta. Para un contenedor que no arrancaste desde Visual Studio, abre Debug > Attach to Process, pon Connection type en Docker (Linux Container) o Docker (Windows Container) según la imagen, y elige el contenedor de la lista. Visual Studio pasa por el daemon de Docker y mete su propio depurador dentro del contenedor en marcha, así que tú nunca añades ninguno a la imagen.

Cómo depurar remotamente una app en Azure App Service

Para una app desplegada en Azure App Service, sáltate la configuración manual del depurador remoto. Haz clic derecho en el proyecto dentro de Solution Explorer, elige Publish, y luego en el menú … del perfil de publicación selecciona Attach Debugger. Visual Studio activa el endpoint de depuración remota en la instancia de App Service y se encarga de la conexión y la autenticación por ti. Una vez conectado, las reglas de símbolos de las secciones anteriores siguen aplicando. Revisa la ventana Modules antes de confiar en un breakpoint.

Depurador remoto o git bisect: cuál usar primero

Un depurador remoto te dice qué está haciendo una línea concreta ahora mismo, en una máquina concreta. No puede decirte qué commit introdujo el problema. git bisect responde justo eso, con una búsqueda binaria sobre el historial en vez de una búsqueda en tu memoria.

Para una regresión, sigue ese orden. Si todavía no sabes qué commit rompió las cosas, haz bisect primero. Cuando tengas el commit y una máquina donde el bug se reproduzca, monta ahí el depurador remoto y averigua por qué.

Artículos relacionados