문제가 문제다(1): 하늘을 보아야 별을 딴다
들어가며
초보 대학원생을 위한 여러 길잡이 책과 강연에 빼놓지 않고 등장하는 것은 연구 문제를 찾는 방법과 과정이다. 초,중,고, 그리고 대학 학부 과정까지는 주로 주어진 문제를 잘 푸는 능력을 기른다. 반면, 대학원 과정에서는 스스로 좋은 문제를 찾고 정의하는 능력을 기르는 것이 훨씬 중요하다. 인류 지성이 아직 도달하지 못한 저 경계 너머 컴컴한 어둠 속을 탐험하는 것이 석박사들의 역할이기 때문이다. 백미터를 제 아무리 빨리 달리는 사람도 거기서는 소용이 없다. 학창시절 빨리 달리기를 배운 까닭은 그 경계까지 무사히 도달하기 위함일 뿐. 경계를 넘어선 이후부터는 딛고 선 곳이 직선 코스인지, 곡선 코스인지, 물인지, 낭떠러지인지 그 누구도 모르기 때문이다. 대학원에서 좋은 문제를 찾는 것이란, 이러한 어둠 속에서 작은 놀이터를 하나 세워서 인류가 여태껏 도달한 지식의 경계를 확장하는 것이라 할 수 있겠다. 많은 사람이 오랫동안 마음껏 뛰놀 수 있도록 튼튼하고도 놀거리가 가득하면 더욱 좋다.
예상하다시피 좋은 문제를 찾는 것은 쉬운 일이 아니다. 그러다보니 대학원에서 좋은 문제를 찾는 것과 관련된 수많은 지혜가 이미 서점과 인터넷에 널려있다. 그런데도 하루가 멀다하고 또 다른 조언이 나타나고 사람들은 이에 귀를 기울인다. 더 이상 새로운 게 있을까 싶은 데도 어김없이 나오는 다이어트 비법서같다. 사실 다이어트건 연구 문제 찾기이건 핵심 비법은 매우 간단하다.
“살을 빼고 싶은 자여, 음식을 적게 섭취하고 운동을 많이 하세요.”
“훌륭한 연구를 하고 싶은 자여, 호기심으로 세상을 보고 과감히 도전하세요.”
당연히 뼈에 새기고 마음에 새겨야할 만고불변 진리이다. 다만, 현실에서는 그 진리가 다양한 길을 통해 다양한 양상으로 발현이 된다. 공통된 진리를 향해 가더라도 모두 가는 길이 다르고 만나는 풍경이 살짝 다르다. 그래서 비법서에 적힌대로 해도 안되는 경우도 있고, 비법서 없이 덤볐는데 잘 되는 경우도 있다.
이 글에서는 최근 우리 연구진이 더듬어 찾은 길과 그 여정을 이야기하고자 한다. 진리가 담긴 경전도 좋지만, 평범한 사람들의 생생한 실제 이야기가 더 가까이 와닿는 법. 비슷한 길을 가는 사람들에게 소박한 참고서가 되었으면 한다. 아래 두 가지 비슷하고도 다른 연구 이야기이다:
하늘을 보아야 별을 딴다: UnitCon 이야기
가만 있지말고 뭐라도 하자는 이야기이다. 대신 남이 정해준 관점이 아니라 자기만의 시선으로. 새로운 연구 주제를 찾는답시고 논문만 줄기차게 읽고 있는 사람들이 있다. 나는 반대다. 물론 가만히 앉아있는것 보다는 훨씬 낫지만, 그건 남이 만든 렌즈로 세상을 보는 격이다. 이미 정교하게 관점이 튜닝된, 수많은 길 중 그들이 성공했던 길만을 보여주는 지도다. 그래서 우리 연구실에 들어오는 학생들에게 남의 논문 읽으면서 연구 시작하기를 권하지 않는다. 남들이 지나간 길에서 남은 고기가 뭐 없나 뒤지는 하이에나가 되길 원치 않으므로. 대신 넓은 초원, 야생 한복판에서 부지런히 뛰어다니며 근육을 기르길 권한다. 우리 연구 분야로 따지만 유명 소프트웨어 GitHub 저장소의 버그 리포트 뒤져보기, 최신 보안 오류 살펴보기, 혹은 소프트웨어 개발 회사에서 일하는 지인의 고충 들어보기, 다른 분야 사람들의 속사정 들여다 보기. 분명 그들을 빡치게 하는 문제가 있을 것이다 (아니 제길 시리즈 참고). 최근 발표된 제 아무리 우수한 논문도 해결하지 못하는, 당장 오늘 개발자 속을 썩이는 문제. 그것이 우리의 사냥감이다. 처음엔 허구헌날 사냥에 실패하여 굶는 날이 많겠지만, 곧 나만의 길을 개척하여 크고 싱싱한 고기를 자주 맛보게 될테니.
이 이야기는 꽤 오래전 2022년 2월로 거슬러 올라간다. 당시 (지금도 마찬가지) 연구실의 관심사는 소프트웨어를 개발해 가는 환경에서 지속적으로 변모하는 (이른 바, CI/CD 환경) 프로그램이 안전한지 늘 검사하는 것이었다. 현장의 프로그램은 하루에도 몇번씩 바뀐다. 다양한 기능 개선, 오류 수정, 코드 정리가 일어난다. 더구나 수많은 개발자들이 협업하며 소프트웨어를 개발하기 때문에, 나도 모르는 새에 동료가 프로그램을 바꿔놓기도 한다. 따라서 그 거대한 프로그램의 시시각각 변화 과정을 사람이 모두 파악하기는 사실상 불가능하다. 자동 도구가 반드시 필요하다.
당시에 이런 문제를 해결하는 기반 기술 중 하나로 지향성 마구실행 기법(directed fuzzing) 연구를 한창 진행중이었다. 오류 의심 지점이 주어지면 그 오류를 발현하는 입력을 자동으로 생성하는 기법이다. 하지만 그 오류 의심 지점을 자동으로 찾는 것은 미뤄둔 상태였다. 당시 갓 석사로 입학한 수진이가 이를 살펴보기로 했다. 소프트웨어 개발 중 코드가 변했을 때 그 변화 때문에 유발되는 오류 의심 지점을 정확하게 집어낼 수 있는가? 실제 오류는 소수이지만 터무니 없는 후보 지점을 너무 많이 고른다면 (가령 수천개) 실제에서 큰 의미가 없을 것이다. 하지만 정적 분석기를 이용하면 어느 정도 의심도가 높은 지점을 정확하게 골라낼 수 있을 거라고 보았다. 그리고 우리는 향후 1-2년간 그런 분석 기술을 만들고 있을 것 같았다. 그때까진 그렇게 생각했다.
메타에서 개발하여 널리 쓰이고 있는 정적 분석기 Infer를 갖고 현 최고 수준이 어느정도 되는지를 가늠해보기로 했다. 여러 유명 프로그램에 있는 이미 알려진 오류를 Infer가 잘 잡아내는가? 메타에서 발표한 논문에 따르면 성능이 매우 좋다고 한다. 하지만 논문 밖 진짜 세상 이야기가 궁금했다. 처음 다루어 보는 도구가 익숙하지 않았겠지만 수진이가 끈기있게 하나하나 조사해갔다. 꼬박 한학기가 걸렸던 것으로 생각한다. 우리의 관찰에 따르면, 많은 경우 오류를 잡아내지 못하였다. 논문만 들여다 보아서는 알 수 없었을 결과이다. 하지만 이것은 논문의 주장이 잘못되었다는 것이 결코 아니다. 모든 경우에 다 잘 통하는 기술이라면 진작에 연구거리도 아니었을 것. 그들은 그들의 길에서 그들의 문제를 잘 푼 것이고, 우리는 우리의 길에서 또 다른 문제를 만나고 있을 뿐이다. 그리고 이런 것들이 모두 모여 기술이 발전한다.
한 학기동안 세상의 온갖 오류를 한껏 만나보고 나니 우리는 미처 생각치 못했던 것을 보게 되었다. 우리가 살펴본 대부분 프로그램은 라이브러리 프로그램이었다. 이런 프로그램의 오류를 발현 시키기 위해서는 오류가 있는 라이브러리 함수를 사용하는 또 다른 “프로그램”을 만들어내야 했다. 반면, 기존에 우리가 연구하던 지향성 마구실행 기술은 입력으로 “값(예: 문자열, 숫자)”을 만들어 내기 때문에 우리가 본 오류에 직접 적용할 수가 없었다. 이런 문제 때문에 특정 의심지점의 오류를 발현 시킬수 있는 작은 “프로그램”, 즉 단위 테스트(unit test)를 자동으로 생성하는 일을 해야겠다는 생각이 들었다. 이른 바, “지향성 단위 테스트 생성기”이다. 수많은 오류의 이유와 이를 발현시키는 단위 테스트를 하나하나 뜯어본 수진이의 제안이었다. 큰 프로그램의 한 구석에 있는 오류를 이해하는 것은 결코 쉽지 않은 일이다. 깊은 빡침에서 우러 나왔음이 확실하다.
그 때부터 오류 의심 위치 선정은 잠시 미루어두고 발현 프로그램을 합성하는 것에 몰두했다. 그렇게 시작한 UnitCon 프로젝트의 첫 커밋을 보니 2022년 8월 4일. 문제를 정의하는데 6개월이 걸렸다. 뜨거운 여름 한 가운데로 기억한다. 사실 단위 테스트 자동 생성 기술은 오랜 역사를 지니고 있다. 하지만 지금까지는 대상 프로그램 전체에 숨어있는 오류를 대상으로 마구 테스트를 생성하는 식이었다. 우리처럼 특정한 의심 지점 (가령, 정적 분석 알람, 최신 변경 지점)을 세밀하게 조준하는 기술은 없었다. 우리가 갖고 있는 정적 분석, 프로그램 합성 기술로 가능하리라고 보았다. 가을학기에 연희가 합류한 것도 없어선 안될 행운이었다. 정적 분석기를 만들어 보고, 회사에서 실전 코드를 많이 다루어 본 경험이 기술 개발에 큰 도움이 되었다. 수진이가 한땀한땀 살펴본 문제점과 아이디어 조각을 연희가 짜맞추고 확장된 방식으로 정리하면, 내가 반례를 찾고 다시 문제점을 지적하는 작업이 반복됐다.
늘 그렇듯 목표에 도달하기까지는 쉽지 않은 여정이 기다리고 있었다. 1년간 온 힘을 다해서 시스템을 만들었다. 지향성 기술은 기존에 없었지만 최소 무지향성 기술보다는 우리 기술이 월등해야 수월성을 주장할 수 있었다. 하지만 10년간 학계 최고 수준이었던 무지향성 도구를 밑바닥에서부터 출발해 따라잡기란 쉽지 않았다. 2023년 여름을 불태우고 9월 FSE에 제출할 계획이었지만, 제출 당일까지 성능이 좋지 않아 결국 내지 못했다. 같이 아쉬움을 달래던 연구실 앞 잔디밭 가을 바람이 제법 선선했다.
그 이후로도 꼬박 1년이 더 걸렸다. 시스템을 갈고 닦아서 다음 해인 2024년 3월 ICSE에 드디어 제출했지만 결과는 처참했다. 우리의 문제 의식에 공감하지 못했고, 확장성에 의문을 제기했다. 안타까웠지만 어느 정도 납득이 되는 비판도 있었기에, 지적받은 약점을 보완하기로 했다. 학부 연구생이었던 희원이도 참여하여 실험을 돕기 시작했다. 또 다시 치열한 절차탁마가 9월까지 계속 됐다. 학교 앞 중국집 원탁에 앉아 논문의 설명을 가다듬던 날이 선명하다. 이제는 자신있다고 생각하고 FSE에 다시 제출했는데 중간 결과가 또 별로 신통치 않았다. 학생들이 실망하면 어쩌나 싶은 생각이 잠시 들었으나, “그래도 저번보다는 점수가 낫잖아요”라며 팔을 걷어붙이는 모습을 보고는 금방 떨쳐버렸다. 역시 맷집은 두둑한 편이 좋다. 우리는 기술에 자신이 있었기에 중간 결과에 대한 저자의 응답을 쓸 때도 거침이 없었다. 평소보다 더 강하게 우리의 주장을 펼치고 오해를 바로 잡았다. 어느 정도 주장이 먹혀들었는지, 몇 달 후 주요 부분을 개선 후 재제출 (major revision)하라는 결과를 받았다. 건설적인 비판이 많았기에 결과를 기쁘게 받아들이곤 개선 작업에 돌입했다.
2025년 4월, 최종 채택 연락을 받았다. 3년이 훌쩍 지나있었다. 우리가 갈아넣은 시간과 노력이 고스란히 UnitCon 시스템에 녹아들어 세상에 공개되는 순간이다. 덤으로 한 달 뒤에는 우리의 연구가 최우수 논문으로 선정되었다는 기쁜 소식도 날아왔다. 우리가 개선한 내용을 심사위원들 모두가 높이 평가한 것으로 보인다. 재제출본이 심사중이던 2월 아침, 출근해서 일을 처리하던 차에 문득 떠올라 학생들에게 슬랙 메세지를 보낸 적이 있다. 중간 평가에서 이 정도 박한 평가를 받을 연구가 아닌데 이상하다고, 후속 연구에서는 최우수 논문을 받을 수 있을거라는 예언이었다. 생각보다 빨리 실현 되었다.
이제 이 장의 제목을 거짓으로 지은 것에 대해 사과를 해야겠다. 사실 “하늘을 보아야 별을 딴다”는 것은 지나치게 낭만적인 이야기일 수 있다. 더 현실적인 버전은 “하수구에 기어들어가 봐야 벌레를 잡는다” 일 것이다. 많은 공학 분야가 그렇고, 특히 우리처럼 소프트웨어 오류(bug, 벌레)가 연구 대상인 경우 더욱 그렇다. 도서관에 앉아 밤낮으로 백과사전에 있는 벌레 그림만 들여다보아서는 벌레 잡는 기계를 만들 수 없다.
그러니 우리 그만 책을 덮고 하수구 뚜껑을 열자. 더럽고 냄새나는 오물에 눈을 찌푸리자. 튀어나오는 바퀴벌레에 소스라치게 놀라자. 정말 드러워서 못봐주겠다고, 꼴도 보기 싫다고 크게 소리치자. 그렇게 차곡차곡 분노와 불만이 쌓였다면 크게 기뻐하자. 드디어 내가 진심을 다해 풀어야할 문제를 찾은 것이니. 그리고 곧 뚜껑을 깨고 높이 승천할 날이 멀지 않았으니.
(두 번째 이야기는 여기에서 이어진다.)