2008년 04월 09일
문제의 해결보다, 원인의 이해가 더 중요한가 봅니다

D-Day를 몇 일 안 남긴, 그야말로 한 시간이 아까운 때였습니다.
항상 바쁠 때면, 예상치 못한 일이 일어나기 마련이죠.
아니나 다를까, 이상한 버그가 발견되었습니다.
2048 octet 이상의 packet을 받으면 tcp/ip protocol task가 crash하여 더 이상 통신이 되지 않는 문제였습니다. Protocol stack은 binary로 제공되기 때문에 문제의 분석이 어렵습니다. 내적인 문제 보다는 외적인 문제 일 것이라는 가정으로 여러 실험을 했습니다. 실험 결과, 1500 octet이상의 packet을 받으면 문제가 발생하더군요. 하지만, 왜 그런 문제가 발생하는지는 알 수 없었죠.
다가오는 D-Day의 압박 속에서 일단 문제를 해결하기로 합니다.
2048 octet으로 보내던 packet의 크기를 1024 octet으로 변경하는 일이었습니다.
(이건 아주 간단하게 수정이 가능합니다)
기능은 이전과 같이 잘 동작하였죠.
문제를 해결하는 데는 채 반나절도 걸리지 않았습니다.
걱정했던 프로젝트 리더는 안도의 한숨을 내쉬었지만,
정작 제 스스로는 문제를 해결했다는 안도감과
원인을 이해하지 못했다는 죄책감 사이에서 고민 하고 있었습니다.
'됐어! 그 정도면, 사용하는 데는 아무런 문제도 없다고'
'그래도, 누가 1500 byte라도 보내 버리면 아직도 문제는 발생하자나!'
'누가 그런 짓을 하겠어. 괜한 걱정이야'
'으음, 영 찝찝해. 문제의 원인을 이해하지 못했으니, 이건 옳은 게 아니야'
이렇게 제 안의 흑과 백이 다투고 있습니다.
그렇게 문제가 지나가는가 했는데,
이틀이 지나도록 그 문제는 제 머리 속을 떠나지 않았습니다.
어느새, 저는 그 문제를 다시 꺼내 들었고,
원인을 이해하기 위해서 수많은 실험과 분석을 다시 시작했습니다.
바쁜데 괜히 시간을 허비하는 것이 아닌가 하는 괴로운 4일째의 저녁 시간에서야
드디어 원인을 이해할 수 있었습니다.
(*** 여기부터 재미없는 기술적인 이야기 입니다.)
global로 char buffer[1024]를 잡았는데, memcpy에서 overflow가 발생하면서 tcp/ip protocol task의 global을 침범하는 문제였습니다. 쉽게 찾을 수 없었던 이유는 문제가 발생한 tcp/ip의 global이 overflow가 된 buffer와 3개 변수만큼 떨어져 있었기 때문이죠. 결국 2개의 추가 global의 내용 또한 overwrite되는 버그였던 것입니다.
참고로, RTOS환경이라 task간의 protection이 존재하지 않기 때문에 이런 문제가 발생하게 됩니다. 속도를 위해서 virtual memory나 User/Kernel space개념도 사용하지 않는 환경이라고 보시면 됩니다.
또 다른 이유는, linker가 global의 순서를 library끼리 가까이 배치할 것이라고 예상을 했었는데, 결과를 보면 아무 상관 관계도 없이 global이 배치 되어 있었던 것이었죠. 이 두 번째 원인이 더 치명적이었는데, 이유는 코드가 추가되어 global의 배치 순서가 변경되면 다른 global을 깨먹게 되는 현상이 발생하기 때문이죠. 아마도 그냥 놔두었으면, 몇 일이 지나 코드가 추가되면서, 지금 발생했던 문제는 스스로 없어지고 또 다른 문제가 발생하는 현상으로 이어졌을 겁니다.
(*** 여기까지가 재미없는 기술적인 이야기 입니다.)
만약, 이런 문제를 해결하지 못하고 Release되었다면, 매우 오랜 기간 동안 다양한 문제를 간헐적으로 일으킬 수 있는 버그가 될 가능성이 높았습니다. 몇 년에 걸쳐서 수십, 수백 시간을 디버깅에 바쳐야 할지도 모르는 아찔함이 느껴집니다.
그렇게, 문제의 원인을 이해하고 나서야
단지 시간이 부족하다는 이유 때문에,
겉에 보이는 문제만을 해결하고, 근본적인 원인은 이해하지 않으려 했던
제 마음가짐의 부족함이 보이는 군요.
제 스스로가 부끄러워지는 순간입니다.
역시,
문제의 해결보다, 원인의 이해가 더 중요한가 봅니다.
# by | 2008/04/09 22:33 | 메인스토리 | 트랙백 | 덧글(20)





☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
원리를 알면 응용력과 창의력이 생기는걸요!
이게 바로 문제 해결력 아니겠어요!!!
근데 그놈의 원리 알기가 항상 쉬운게 아니란게 좀 .... ㅡ_ㅡ;;;
문제를 해결하지 못하면 주말이 편하지 않아요 -_-
영회님// 영회님이야 깔끔하신 분의 이미지를 가지고 있어서 그런지, 일처리가 확실하실 것 같다는 느낌이 듭니다. 제가 맞죠?
션님// 싱크빅 선전 문구 같은데요. ㅎㅎ 그런데 절묘하게 맞아 떨어지는 군요. 역시 션님의 재치는 참으로... 하하
멤피스님// 역시 True 엔지니어 다우십니다. 그런 정신을 가진 동료와 함께 일하는 것은, 그 당시는 조금 괴롭지만, 길게 보면 언제나 즐거운 일인 것 같아요.
쉬는날마다 비가와서 슬퍼요.. 하하;;;
실제로 벌어지기는 것을 생각보다 많이 경험하면서 삶니다.
예로는 우리 신병이 관물대 겉만 정리하는 경우...
문제의 근원을 제거하기 위해서 내리갈굼이라는 정신교육을 행합니다.
이것도 일종의 실제적인 디버깅이라고 할수있겠죠?
좋은 글 잘보고 갑니다. ;)
구루마루님// 역시 대단하시네요. 수 년 동안 내려오는 당연함에 도전하는 일은 결코 쉽지 않을 일인 것 같거든요. 기술적에서나, 정치적에서나 말이죠. 훌륭하네요.
Paromix님// 그렇죠. 현상을 해결한 거죠. 단어만 보아도 알 수 있는 군요. 진정한 엔지니어들은 이렇게 이야기를 하고, 그렇지 않은 분들은 해결했다고 하겠군요. 하하. 궂은 환경이 훌륭한 엔지니어를 만들어 내듯이, 궂은 날씨가 멋진 사진을 만들어 내기도 해요. 우산 쓰고 카메라를 들고 나가보시길~
Loondark님// 자주 오시네요. 어찌 된 거죠? 당연히 반갑고요.
생활적인 이야기에 철학적 질문을 하시니 하하.
우리의 삶 자체가 디버깅 같다는 생각 늘 하고 삽니다.
디버깅의 좋은 예네요. Target이 신병이라는 것이 조금 독특하지만요.
kkamagui님// 후자도 상당히 많은 것 같아요. 어쩌면 두 가지는 연결되어 있는지도 모르죠. 시간이 없으니 대충 넘어 갈 수 밖에 없고, 또 그런 것들이 발견되어도 덮어버릴 수 밖에 없는 그런 상황인 것 같네요. 시간을 줄이면, 엔지니어는 품질을 포기하게 된다는 말이 생각나는 부분입니다.
부대에 "인터넷 방" 이라는 인터넷을 사용할수 있도록 하는 곳이 생겨서
주에 1시간정도 사용할수 있어요.
그나저나 주 1시간으로는 공부에 턱없이 부족할 것 같네요.
휴가 기간동안 즐겁게 보내시고요. loondark님~
정말 공감되는 내용이네요... 원인을 모른 채 땜질 형식으로
문제를 덮어나갈 때의 불안함과,
다음에 뻔히 닥쳐올 '다른 문제들' 의 압박감은.. 정말
당해보지 않은 사람은 모르는 것 같습니다 ^^;
돌아보면 정말 어이없는 사소한 오류가 원인인 경우가 많지만
그 당시에는 데드라인이 다가오면서 사고가 마비되는 것 같네요..
현실과 이상의 차이랄까? 그때 필요한 것이 용기인 것 같다는 생각이 드네요.
그리고 그 용기의 근원은 멀리 볼 수 있는 시야라고 생각하고요.