본문 바로가기
프로그래밍

👨‍💻 [Go] Go 에서 프로그램이 비정상 종료 될 때, 오류 분석을 위한 덤프 파일을 생성하는 방법은 어떻게 되나요?

by 밝음의기둥 2025. 1. 20.
반응형

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."


👨‍💻 안녕하세요, 윌리 프로젝트의 윌리 입니다.

Go 에서 프로그램이 비정상 종료 될 때, 오류 분석을 위한 덤프 파일을 생성하는 방법은 어떻게 되는지 간략히 알아보았습니다.


질문 >

Go 에서 프로그램이 비정상 종료 될 때, 오류 분석을 위한 덤프 파일을 생성하는 방법은 어떻게 되나요?

답변 >

Go에서 프로그램이 비정상 종료될 때 오류 분석을 위한 덤프 파일을 생성하려면 스택 트레이스(Stack Trace)프로파일 데이터를 기록하거나, 운영 체제에서 제공하는 코어 덤프(Core Dump)를 생성하도록 설정해야 합니다. 아래는 이러한 방법들을 구현하는 단계별 가이드입니다.


1. 스택 트레이스 기록

비정상 종료(SIGSEGV, SIGABRT 등) 시 스택 트레이스를 덤프 파일로 저장하면 디버깅에 유용합니다.

코드 예제

package main

import (
	"fmt"
	"os"
	"os/signal"
	"runtime"
	"syscall"
)

func writeStackTrace() {
	// 스택 트레이스 버퍼 생성
	buf := make([]byte, 1<<20) // 1MB 크기
	stackSize := runtime.Stack(buf, true)

	// 덤프 파일 생성
	file, err := os.Create("stack_trace.log")
	if err != nil {
		fmt.Printf("Error creating stack trace file: %v\\n", err)
		return
	}
	defer file.Close()

	// 스택 트레이스 기록
	file.Write(buf[:stackSize])
	fmt.Println("Stack trace saved to stack_trace.log")
}

func main() {
	// SIGSEGV, SIGABRT 같은 종료 신호 처리
	signals := make(chan os.Signal, 1)
	signal.Notify(signals, syscall.SIGSEGV, syscall.SIGABRT, syscall.SIGINT)

	go func() {
		for sig := range signals {
			fmt.Printf("Received signal: %v\\n", sig)
			writeStackTrace()
			os.Exit(1) // 종료 코드 1로 비정상 종료 처리
		}
	}()

	// 예제: 비정상 종료 유발
	var invalidPointer *int
	*invalidPointer = 42 // SIGSEGV 발생
}


2. Go 프로파일링 데이터 기록

Go의 runtime/pprof를 사용하면 실행 중 CPU 및 메모리 사용 프로파일을 생성할 수 있습니다.

CPU 프로파일 생성

package main

import (
	"os"
	"runtime/pprof"
)

func main() {
	f, err := os.Create("cpu.prof")
	if err != nil {
		panic(err)
	}
	defer f.Close()

	// CPU 프로파일링 시작
	pprof.StartCPUProfile(f)
	defer pprof.StopCPUProfile()

	// 예제 작업
	for i := 0; i < 1_000_000; i++ {
		_ = i * i
	}
}

메모리 프로파일 생성

package main

import (
	"os"
	"runtime"
	"runtime/pprof"
)

func main() {
	f, err := os.Create("memory.prof")
	if err != nil {
		panic(err)
	}
	defer f.Close()

	// 메모리 프로파일 기록
	runtime.GC() // 가비지 컬렉션 실행
	pprof.WriteHeapProfile(f)
}

프로파일 데이터 분석

생성된 프로파일 파일(cpu.prof, memory.prof)은 go tool pprof를 사용하여 분석할 수 있습니다.

go tool pprof cpu.prof


3. 코어 덤프 설정 (OS 기반)

코어 덤프는 운영 체제가 프로세스의 메모리 상태를 저장한 파일로, Go 런타임 외부에서 메모리 상태를 분석하는 데 유용합니다.

3.1. 코어 덤프 활성화

Linux에서 코어 덤프를 활성화하려면 다음 명령어를 사용합니다:

ulimit -c unlimited

3.2. 코어 덤프 파일 경로 설정

코어 덤프 파일의 저장 경로를 설정합니다:

echo "/tmp/core.%e.%p" | sudo tee /proc/sys/kernel/core_pattern

  • %e: 실행 파일 이름
  • %p: 프로세스 ID

3.3. 비정상 종료 시 코어 덤프 생성

Go 프로그램이 비정상 종료되면 /tmp/core.<binary-name>.<pid>에 코어 덤프가 생성됩니다.

3.4. 코어 덤프 분석

gdb를 사용하여 코어 덤프를 분석합니다.

gdb ./your-go-binary /tmp/core.<binary-name>.<pid>


4. 실제 사용 시나리오

  1. 비정상 종료 감지 및 스택 트레이스 기록:
    • os/signal과 runtime.Stack를 조합하여 로그 파일을 남깁니다.
  2. 프로파일링 활성화:
    • runtime/pprof를 통해 CPU, 메모리 사용 프로파일을 기록합니다.
  3. 운영 체제 기반 코어 덤프:
    • 운영 체제의 코어 덤프 설정을 활용하여 프로세스 메모리 상태를 분석합니다.

5. 장단점 

방법 장점 단점
스택 트레이스 기록 Go 런타임의 고루틴 상태를 즉시 확인 가능 메모리, CPU 사용 정보 부족
Go 프로파일링 세밀한 실행 분석 가능 (CPU, 메모리, 고루틴 상태) 비정상 종료 직후의 상태를 기록하는 데는 적합하지 않음
코어 덤프 전체 메모리 상태 및 OS 레벨 디버깅 가능 분석에 추가 도구(gdb) 필요

6. 요약

Go에서 비정상 종료 시 덤프 파일을 생성하는 방법:

  1. 스택 트레이스 기록: runtime.Stack로 스택 덤프 생성.
  2. 프로파일 데이터 기록: runtime/pprof로 CPU, 메모리 상태 기록.
  3. 코어 덤프 생성: OS 설정(ulimit, /proc/sys/kernel/core_pattern)으로 메모리 상태 저장.

위 방법들을 조합하여 프로그램 종료 원인을 효과적으로 분석하고 디버깅할 수 있습니다.



🎬 유튜브 채널 🎬

 

위로그@WiLog

📢 안녕하세요, 위로그@WiLog 시청자 여러분, 저는 윌리(Willee) 입니다. 📢 위로그@WiLog 는 자기계발을 목적으로 하는 채널 입니다. 📢 오늘도 즐겁게~ 자신을 위한 계발을 함께 해보아요~ d^_^b 📌

www.youtube.com

🎬 치지직 채널 🎬

 

위로그 채널 - CHZZK

지금, 스트리밍이 시작됩니다. 치지직-

chzzk.naver.com


반응형