C 프로그램을 위한 동시성 커버리지 측정 기법 송지영 SWTV KAIST
동시성 VS 순차 커버리지 Test suite A Test suite B 1 : 2 : … 20 : 1 : 2 : … 20: 60% 80% 테스팅에서 커버리지는 테스트의 질을 평가하는데 쓰입니다. 테스트 스윗은 테스트케이스의 묶음이고 여기 두개의 테스트스윗이 있습니다. 각각 60, 80%를 커버한다면 우리는 더 많은 코드를 커버하여 버그를 잡을 가능성을 높인 테스트 스윗 B를 선택합니다 순차 프로그램과 다르게 동시성 프로그램은 스레드 스케줄링에 따라 결과가 다양한 output을 가짐 그러므로, 수행되는 코드뿐 아니라 스레드 인터리브도 커버리지 요구사항으로 고려해야 함 2014-07-30 C 프로그램을 위한 동시성 커버리지 측정 기법
Motivation example -5? 코드수행만을 요구사항으로 간주하면 100% 커버리지를 달성하여도 bug를 찾지 못하는 경우가 발생 다음 2 테스트케이스로 분기 커버리지 100% 달성 Tc1: balance 10, withdraw(5) Tc2: balance 5, withdraw(10) 1: void* withdraw(long x){ 2: if(balance >= x){ 3: t = balance; 4: balance = balance-x ; 5: } 6: } 예제를 들어 설명하겠습니다. 코드수행~. 이 예제는 계좌에서 돈을 인출하는 프로그램입니다 잔고가 10, 5를 인출하는 test case1 에서는 if branch를 커버하고 잔고가 5, 10을 인출하는 test case 2에서는 else 브랜치를 커버합니다. 이렇게 코드 커버리지 100%를 달성했다고 버그가 없을까요? 절대 그렇지 않습니다. 동시성 프로그램에서 이와같은 스레드 스케줄링에서는 에러없이 수행되지만, 이런 스레드 인터리빙이 있는 스케줄에서는 10을 인출하고 5를 인출합니다 그러면 잔고가 -5가 되는 버그가 발생합니다. Initially, balance:10 -t1: withdraw(10) – 2 if(balance>=10) 3 t = balance 4 balance=t–10 -t2: withdraw(5) – 2 if(balance>=5) 4 balance=t–5 Initially, balance:10 -t1: withdraw(10) – 2 if(balance>=10) 3 t = balance 4 balance=t–10 -t2: withdraw(5) – 2 if(balance>=5) -5? 스레드 인터리브도 커버리지 요구사항으로 고려해야 함 2014-07-30 C 프로그램을 위한 동시성 커버리지 측정 기법
동시성 커버리지 측정기법 Synchronization coverage: synchronization-pair Lock으로 각 스레드가 동기화되는 것을 확인하기 위해 사용 Data access coverage: def-use 공유변수 값을 정의하고 사용하는 위치를 확인하기 위해 사용 동시성 커버리지 측정기법으로는 크게 두 가지가 있습니다. 첫번째로는 Synchronization coverage로 pthread_mutex_lock이나 cond_wait, signal과 같이 lock으로 각 스레드가 동기화 되는 것을 확인하기 위해 사용합니다. data access coverage~ 대표적으로 synchronization coverage에 대해 설명해드리겠습니다. 2014-07-30 C 프로그램을 위한 동시성 커버리지 측정 기법
Synchronization coverage Synchronization-pair: - 스레드 인터리브가 발생할 때 lock으로 공유 변수를 동기화하기 위해 사용 - coverage requirement는 code location 쌍 < 𝒍 𝟏 , 𝒍 𝟐 > 이다. - 𝑙1과 𝑙2 는 같은 lock 을 가진 lock statement이며, 𝑙2는 𝑙1 의 lock이 unlock된 후 최초로 같은 lock 을 hold하는 구문이다. Coverage requirement는 code location 쌍입니다. 11번 라인에서 lock m 을 잡고 21번라인에서 최초로 같은 lock을 잡게 되면 우리는 11,21쌍이 커버되었다고 합니다. 마찬가지로 21,23쌍이 커버가 됨을 알 수 있습니다. 커버되지 않은 쌍으로는 21,11 23,11이 있는데, 커버리지를 높이기 위해서 스레드 스케줄링을 달리한 테스트 케이스를 만들 수 있습니다. 이와같은 스레드 스케줄링에서는 21,11을 커버할수 있고 이런 스케줄링은 23,11을 커버할 수 있습니다. --Thread1: foo()-- --Thread2: bar()-- 11:pthread_mutex_lock(m); 12:pthread_mutex_unlock(m); 23:pthread_mutex_lock(m); 24:pthread_mutex_unlock(m); 21:pthread_mutex_lock(m); 22:pthread_mutex_unlock(m); --Thread1: foo()-- --Thread2: bar()-- 11:pthread_mutex_lock(m); 12:pthread_mutex_unlock(m); 23:pthread_mutex_lock(m); 24:pthread_mutex_unlock(m); 21:pthread_mutex_lock(m); 23:pthread_mutex_unlock(m); --Thread1: foo()-- --Thread2: bar()-- 11:pthread_mutex_lock(m); 12:pthread_mutex_unlock(m); 23:pthread_mutex_lock(m); 24:pthread_mutex_unlock(m); 21:pthread_mutex_lock(m); 23:pthread_mutex_unlock(m); Covered SPs: (11, 21), (21, 23) (11, 21) is covered Uncovered SPs: (21, 11), (23, 11) (21, 23) is covered 2014-07-30 C 프로그램을 위한 동시성 커버리지 측정 기법
Future work C/C++ 타겟 코드의 정적 분석와 동적 분석을 통해 발생 가능한 커버리지 condition 찾기 공유변수 찾기, lock의 포인터 변수 찾기 Pbzip2, pfscan 프로그램에 대해 테스트 수행 예정 앞서 살펴본 바와 같이 cover한 쌍과 uncover한 쌍의 전체 집합을 알기 위해서는 타겟코드의 정적분석과 동적 분석을 통해 가능합니다. 2014-07-30 C 프로그램을 위한 동시성 커버리지 측정 기법