Ubuntu 환경에서 .NET Core 애플리케이션의 High CPU 분석 가이드


다음은 Ubuntu (16.04)에서 수행하는 .NET Core 2.0 기반의 애플리케이션에서 high CPU hang 현상이 발생할 경우에 디버깅하는 방법에 대한 팁이다.

먼저 해당 애플리케이션이 CPU 사용량이 많다는 것을 확인할 수 있는 간단한 방법은 terminal 에서 top 명령어를 수행하는 것이다. 아래는 dotnet 관련 process의 CPU 사용량이 72.8%임을 확인할 수 있다.

이후에 원인을 찾기 위해 해당 프로세스에 lldb 디버거를 attach하여 애플리케이션의 동작을 살펴보자. top 명령의 출력에서 확인할 수 있었던 pid(4359)값을 이용하여 해당 프로세스에 lldb를 attach할 수 있다. (process attach –p <pid>)

중요한 점은 디버거에서 많은 CPU를 점유하고있는 thread 를 찾아야 한다. 해당 process에서 CPU 점유가 많은 thread를 확인하는 방법은 ps 명령어를 이용하는 방법이 있다. 다음의 ps명령어는 많은 CPU(83.3%)를 점유하고 있는 thread의 tid(4367)를 찾을 수 있다. < ps –eLo pid,llwp,ruser,pcpu,args >

이제 lldb 디버거에서 해당 thread를 살펴볼 차레이다. 먼저, thread list 명령은 tid값이 4367인 thread를 확인할 수 있다.

해당 thread는 managed thread 이므로, libsosplugin.so를 이용하여 동작중인 callstack을 확인해야 한다. 그러므로, 다음과 같은 명령을 통해서 libsosplugin.so를 디버거에 load한다.

 plugin load /usr/share/dotnet/shared/Microsoft.NETCore.App/2.0.0/libsosplugin.so
 setclrpath /usr/share/dotnet/shared/Microsoft.NETCore.App/2.0.0

Libsosplugin.so가 load 된 이후에 clrthreads를 통해 실제 접근해야할 managed thread의 정보를 얻을 수 있다.

Thread list 명령에서 확인된 tid값 4367은 hex값으로 110f 이다. 그러므로, OSID값이 110f인 managed thread를 확인하기 위해 setsostid 명령을 통해서 다음과 같이 해당 thread로 설정한다.

 setsostid 110f 4

이후에 “clrstack” 명령을 통해 해당 thread에 대한 callstack을 살펴볼 수 있다.

그 다음은 해당 코드를 리뷰해서 CPU 점유율이 높은 이유에 대해서 찾아야 한다. 실제, 코드를 살펴보면 while 구문안에서 뭔가를 처리하고 있는 것을 확인할 수 있다.

해당 코드는 stackoverflow에서 제공하는 sample code를 이용하여 테스트하였다. 위치는 https://stackoverflow.com/questions/2514544/simulate-steady-cpu-load-and-spikes 에 존재하며, Guido Zanon이 제공한 코드를 이용하여 high CPU를 재현하였다.

그런데, sample 애플리케이션은 어떻게 빌드했을까? 그에 대한 간단한 절차는 다음과 같다.
우선 .NET Core 2.0 SDK를 다음과 같이 설치한다.

 sudo apt-get install curl
 curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
 sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg
 sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-xenial-prod xenial main" > /etc/apt/sources.list.d/dotnetdev.list'
 sudo apt-get update
 sudo apt-get install dotnet-sdk-2.0.0

그리고, 이어서 VS Code 를 설치한다.

 sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list'
 sudo apt-get update
 sudo apt-get install code

이후에 기본적인 console 애플리케이션 project는 다음과 같이 생성할 수 있다.

mkdir demo3
cd demo3
dotnet new console

그리고, VS Code 를 실행한 후에, 폴더열기를 해서 생성한 demo3 폴더를 오픈하면, 기본적인 console 애플리케이션 프로젝트가 VS code 안에서 열린다.

이후 sample code를 copy & paste 한 후에 다음을 실행하면 된다.

 dotnet run
 dotnet restore

결국 copy & paste 가 모든 것을 다했다.


Comments (0)

Skip to main content