다음은 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 가 모든 것을 다했다.