Fundamentos de depuración en Go
10 ejemplos para empezar con Escenarios de Defectos - 7 básicos y 3 intermedios.
Busca en todas las páginas de la documentación
10 ejemplos para empezar con Escenarios de Defectos - 7 básicos y 3 intermedios.
go install github.com/go-delve/delve/cmd/dlv@latest.mkdir debuglab && cd debuglab && go mod init example.com/debuglab.main.go o archivos de prueba y ejecútalos con go run . o go test -v.Registra valores con formato que expone el tipo y la estructura.
package main
import "fmt"
func main() {
s := []int{1, 2, 3}
fmt.Printf("s=%#v len=%d cap=%d\n", s, len(s), cap(s))
}%#v imprime la representación de sintaxis de Go, útil para slices nil vs vacíos.len y cap al depurar errores de append y sub-slices.log.Printf en servidores para que aparezcan las marcas de tiempo y las líneas de archivo.Relacionado: Copia de Cabecera de Slice y Sorpresa de Append - cuando len/cap mienten
Envuelve errores e imprime antes de salir.
package main
import (
"fmt"
"log"
"os"
)
func loadConfig(path string) error {
_, err := os.Open(path)
if err != nil {
return fmt.Errorf("loadConfig(%q): %w", path, err)
}
return nil
}
func main() {
if err := loadConfig("missing.yaml"); err != nil {
log.Fatalf("startup failed: %v", err)
}
}%w preserva la cadena de errores para errors.Is y errors.As.log.Fatalf sale con código 1 después de imprimir.Relacionado: Depuración en Go: Fallos Observables y Bordes Afilados - familias de síntomas
Desencadena un puntero nil para estudiar la salida de la pila.
package main
type Store struct{}
func (s *Store) Get() int { return 1 }
func main() {
var s *Store
_ = s.Get() // panic: nil pointer
}GOTRACEBACK=all para obtener pilas completas, incluidos los marcos del runtime.Relacionado: Recorrido de Defectos de Interfaz Nil vs Puntero Nil - trampas de nil tipado
Inicia una sesión de depuración en un programa simple.
package main
import "fmt"
func sum(nums []int) int {
total := 0
for _, n := range nums {
total += n
}
return total
}
func main() {
fmt.Println(sum([]int{1, 2, 3}))
}dlv debug .
# en el prompt de (dlv):
break main.sum
continue
print total
nextdlv debug . compila e inicia bajo el depurador.break establece un punto de interrupción; continue se ejecuta hasta que lo alcanza.next avanza línea por línea; step entra en llamadas.Relacionado: Depuración con Delve - referencia completa de Delve
Lista las goroutines al depurar concurrencia.
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println("work")
}()
}
wg.Wait()
}dlv debug .
break main.main
continue
goroutinesgoroutines lista cada goroutine con un fragmento de pila.goroutine <id> bt para un rastreo completo de una goroutine.Relacionado: Fugas de Goroutine y Cancelación de Contexto Perdida - pilas bloqueadas
Detecta acceso no sincronizado durante las pruebas.
package counter
import "testing"
var n int
func Inc() { n++ }
func TestInc(t *testing.T) {
done := make(chan struct{})
go func() { Inc(); close(done) }()
Inc()
<-done
}go test -race ./...-race instrumenta el acceso a la memoria e informa sobre lecturas/escrituras concurrentes.-race en CI para paquetes que comparten estado mutable.Relacionado: Escenarios de Carreras de Datos y Correcciones del Detector de Carreras - patrones de corrección
Expone pprof para búsquedas de fugas.
package main
import (
"log"
"net/http"
_ "net/http/pprof"
)
func main() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}go run .
# otra terminal:
curl -s localhost:6060/debug/pprof/goroutine?debug=1 | head_ "net/http/pprof" registra manejadores en DefaultServeMux.Relacionado: Fugas de Goroutine y Cancelación de Contexto Perdida - interpreta perfiles
Detente dentro de una función de prueba fallida.
package mathutil
import "testing"
func Add(a, b int) int { return a + b }
func TestAdd(t *testing.T) {
got := Add(2, 2)
if got != 4 {
t.Fatalf("got %d want 4", got)
}
}dlv test . -- -test.run TestAdd
break mathutil.TestAdd
continue
print gotdlv test envuelve go test con soporte de depuración.--.Relacionado: Depuración con Delve - flujos de trabajo de
dlv test
Vincula los registros con los IDs de solicitud durante la depuración del manejador.
package main
import (
"context"
"log"
"net/http"
)
type ctxKey string
const requestIDKey ctxKey = "requestID"
func withID(ctx context.Context, id string) context.Context {
return context.WithValue(ctx, requestIDKey, id)
}
func idFrom(ctx context.Context) string {
v, _ := ctx.Value(requestIDKey).(string)
return v
}
func handler(w http.ResponseWriter, r *http.Request) {
ctx := withID(r.Context(), "req-42")
if err := work(ctx); err != nil {
log.Printf("request_id=%s err=%v", idFrom(ctx), err)
http.Error(w, "error", http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
}
func work(ctx context.Context) error { return nil }
func main() {
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe(":8080", nil))
}context.Context en lugar de variables globales.request_id en cada ruta de error para correlacionar con rastreos.r.Context() a I/O descendente para que la cancelación aparezca en los perfiles.Relacionado: Fugas de Goroutine y Cancelación de Contexto Perdida - ctx en manejadores
Depura defectos relacionados con el tiempo con ubicaciones explícitas.
package main
import (
"fmt"
"time"
)
func main() {
utc := time.Date(2026, 7, 15, 12, 0, 0, 0, time.UTC)
local, err := time.Parse(time.RFC3339, "2026-07-15T12:00:00-07:00")
if err != nil {
panic(err)
}
fmt.Println("utc", utc.Format(time.RFC3339))
fmt.Println("local", local.Format(time.RFC3339))
fmt.Println("equal?", utc.Equal(local))
}time.Parse sin zona en el layout usa UTC para cadenas sin desplazamiento.Equal compara instantes; la salida de Format depende de Location().t.Location() y RFC3339 al depurar errores de marca de tiempo.Relacionado: Zonas Horarias y Trampas de time.Parse - bordes de JSON y DST
Versiones de pila: Esta página fue escrita para Go 1.26.x (predeterminado Green Tea GC, go fix modernizers - verifica el parche en la compilación), chi (última - verifica en la compilación), gin (última - verifica en la compilación), echo (última - verifica en la compilación), google.golang.org/grpc (última - verifica en la compilación), sigs.k8s.io/controller-runtime (última - verifica en la compilación), kubebuilder (última - verifica en la compilación), tinygo (última - verifica los objetivos de placa en la compilación), wazero (última - verifica en la compilación) y golangci-lint (última - verifica el conjunto de linters en la compilación).
Revisado por Chris St. John·Última actualización: 18 jul 2026