Rust 프로젝트 - 정적 Deadlock 분석

유형주·2022년 10월 6일
0

Rust 프로그래밍 언어는 시스템 개발에 특화된 언어로 현재 시스템 분야의 대부분을 점 유하고 있는 C와 비교하여 큰 장점을 가진 언어이다. Rust는 변수에 오너십이라는 개념을 도입하여 메모리 관리를 효율적으로 하여 런타임 오 류를 컴파일 타임에 방지할 수 있으며 Cargo 프로젝트 개발 툴을 지원하여 패키지 관리 와 빌드에 매우 용이하다. 그러나 컴파일 타임에 검출하지 못하는 멀티쓰레드 환경에서의 오류는 아직 Rust언어의 특성을 고려한 충분한 연구가 되어있지 않다. 그래서 Rust 언어로 만들어진 오픈소스 프로젝트 중 개발자들의 코멘트가 많은 레포지토리 10여개를 선정하여 동시성 오류를 분석/분류하였다.




분류결과 깃허브 이슈에서 Deadlock 버그가 가장 빈번하게 리포트되었음을 알게되었고, static한 코드 분석을 통해 Deadlock버그를 검출하는 프로젝트에 착수했다.




기존의 Deadlock 을 검출하는 하나의 방법으로 lock graph algorithm이 존재한다. 이 알고리즘은 하나의 lock의 critical section에서 또 다른 lock에 접근하는 경우 두 lock사이에 edge를 생성하고, cycle이 완성되는 경우, deadlock이라고 판단한다. 그러나 구현 중 깨달은 사실은, 이 알고리즘은 Runtime Detection에 특화되어있다는 것이었다.

Rust는 C, C++, java와 달리 critical section이 lock함수와 unlock함수 사이로 지정되어 있지 않다. 러스트의 오너쉽 개념 때문에 lock의 critical section은 해당 lock 에 접근한 가장 가까운 block으로 지정된다. 또한 read/write lock함수의 사용이 많으 며 이 함수를 사용 할 때에 os의 스케줄링 방식에 기반한 Deadlock 오류도 존재한다.

Lock graph algorithm에 기반을 두되, Rust의 특성을 반영한 코드 분석기, 정적 분석을 가능하게 하는 Deadlock 감지 알고리즘을 새로 짜야했다.
(알고리즘만 따로 추후에 포스팅__)




완성된 프로젝트의 전체 구조는 다음과 같다.
File analyzer는 각각의 rust 파일들에 대해서 이 tree구조를 관리하고, 이를 분석하여 정의된 함수들의 클래스의 구조, 리턴타입 등의 정보를 미리 저장한다. 이 작업이 끝나고 나면, analyzer는 main함수를 찾아내어, 한줄 씩 분석한다. 이때, 변수를 선언하는 경우, 앞서 저장된 리턴타입 정보를 기반으로 타입을 검출하여, 이를 symbol table에 관리한다. 또한 함수를 부르는 경우에는, 관리하는 tree내에 해당 함수노드가 존재할경우, 해당 노드로 분기하여 로직을 계속 진행한다. 이렇게 로직을 진행하다가, lock을 얻는 라인을 발견할 경우, 해당 정보를 concurrent하게 실행중인 detector 에게 전송하도록 하였다.




https://youtu.be/kuXc4lbnkGg

리포트된 버그 결과를 개발자들이 많이 사용하는 vscode의 extension을 통해서 분석기를 활용할 수 있도록 확장하였다. 이 기능은 실제로 deadlock을 구성하는 각각의 코드 line을 하이 라이트하여 개발자들이 쉽게 오류를 파악할 수 있도록 하였다.


Deadlock 버그 감지할 Rust 프로젝트 선택


Deadlock을 발생시킬 가능성이 있는 코드 라인에 빨간줄이 그어짐




https://github.com/Yuhyeingjoo/Rust-DeadLock-Static-Analyzer

0개의 댓글