버그를 해결하기 위해 모든 길을 다 썼을 때해야 할 일


13

저는 크로스 플랫폼 모바일 애플리케이션 (1 인 팀-그 자체만으로)에서 일하는 주니어 프로그래머 (지금까지 경력 4 개월)입니다.

이 프로그램 / 응용 프로그램에 꽤 큰 버그가 있습니다 (각각 자신의 cpp 파일이있는 30 개의 다른 헤더 파일). 나는 버그로 무슨 일이 일어나고 있는지 정확하게 추적하려고 노력하고 있으며 수정하기도합니다 (일부 해킹을 사용하여 문제를 해결하려고 시도했지만) 약 12 ​​가지 이상의 솔루션 (문제를 일으키는 원인이 있음) ) 나는 버그가 무엇인지 또는 버그를 정확하게 추적하도록 이끌지 못했습니다.

당신은 몇 가지 광범위한 기술의 주니어 프로그래머 (런닝, 모든 코드를 종이에 인쇄하고 펜으로 처리하는 등)에 대한 조언이 있습니까?이 버그를 도와 줄 수 있습니까?

내 버그에 대해 좀 더 컨텍스트를 제공합니다. 크로스 플랫폼 API Mosync와 관련이 있습니다. 특정 일련의 작업을 수행 할 때 현재 화면이 다시 표시되지 않으며 이전 화면이 여전히 현재 화면이 아닌 포인터 / 키 프레스 이벤트를 받고 있음을 나타냅니다.

특정 순서 :
-메뉴 화면 표시- "이전 주문 표시 버튼"클릭
-이전 주문 화면 표시- "파일로드"를 클릭 한 다음 메뉴 버튼 클릭 및 배송 화면 열기
-배송 화면 표시-메뉴 버튼 클릭 및 구매 화면 열기
-구매 화면 표시 -여기에 오류가 발생했습니다.이 화면에 대한 입력이 표시 / 반응되지 않습니다. ListView가 스크롤되지 않음, 버튼이 클릭에 반응하지 않음, ListView 셀이 클릭에 응답하지 않음


나는 조언을 취할 것입니다. 버그는 매번 같은 단계를 따라 100 % 재현 할 수 있습니다.하지만 포인터 이벤트가 어떻게 전송되고 있는지, API의 일부로 인해 어떤 화면으로 전달되는지 파악하는 것은 여전히 ​​어렵습니다. 도달 (또는 방법을 모름).

또한 나는 다른 한 쌍의 눈이 내 일을 끝내고 버그를 지적하고 싶지만, 내가 1 인 팀이라고 말했을 때 상사가 나를 지시하고, 그는 회사를 소유하고 앱에 대한 아이디어를 가지고 있지만 C ++ 또는 최근 언어를 모릅니다 (코발? 나는 전부라고 생각합니다). 회사의 지적 코드 / 재산을 위반하거나 과시하지 않고 두 번째 눈을 얻는 방법에 대한 조언이 있습니까?

...이 유급 인턴쉽을 떠나는 것은 선택 사항이 아닙니다. 계약에 따르면 1,200 만 번째 계약 중 6 백만 번째 전에 떠나면 연봉의 30 %를 지불 할 가능성이 있습니다


6
100 % 재현 할 수 있습니까?

5
간단한 대답은 동료를 참여시키는 것 입니다. 팀으로서 당신은 순간에 그것을 해결할 것입니다.
Fattie

2
@ 조-항상 그런 것은 아닙니다. 예를 들어, 서로 다른 서브 시스템이 역할의 미묘하게 호환되지 않는 관점으로 구축 된 여러 복잡한 상호 작용 서브 시스템의 집합 적 동작 버그-사양에 명백하지 않은 모호성으로 인해 일반적으로 극소수의 사람들이 여러 서브 시스템과 상호 작용에 대한 자세한 지식을 가지고 있음 이러한 문제를 진단 할 수 있습니다. 때로는 모든 팀과 대화 해야 하고, 두 사람이 서로 moron을 부르기 시작할 때, 서로 호환되지 않는 가정과 관련이있는 말을 할 가능성이 있습니다.
Steve314

계정을 병합했습니다. Yahoo OpenID를 사용하여 로그인 할 수 있습니다. 또한 답변으로 게시 한 정보를 포함하도록 질문을 편집하고 있습니다.
Adam Lear

btw. 아래의 답변 외에도 위키 백과에서 Mosync가 더 이상 유지되지 않는다고 읽었습니다.
Brad Thomas

답변:


19

100 %의 시간으로 문제를 재현 할 수 있으면 마지막 단계에서 가능한 한 빨리 중단 점을 설정하십시오. 전체 호출 스택을 살펴보면 예상치 못한 값이나 호출해야하지만 그렇지 않은 값이 나올 것입니다.

편집하다:

그리고 당신이 당신의 지혜의 끝에 앉아 버그를 수정하려고 노력하고 여기에 빛의 조언을 얻을 수 있기를 희망하는 게시물을 올리려면 걸어 가십시오 . 고개를 숙이고 나중에 (바람직하게 내일 또는 주말에) 돌아 오십시오. 하루 종일 특정 문제에 대한 해결책을 찾기 위해 하루 종일 보냈으며, 다음 날에 명확한 머리로 돌아와서 10 분 안에 그것을 찾으십시오.


4
어떤 이유로 든 디버거를 사용할 수없는 경우 함수 호출을 텍스트 파일에 기록하는 실패한 코드 비트 주위에 추적 정보를 넣으십시오.

3
"도보"에 +1 걸어 갈 때 문제에 대해 망치는 것보다 생산적 일 것임을 아는 데 많은 경험이 필요합니다. 당신의 상황은 그 특정한 경험을 모으기 시작하기에 좋은 곳인 것 같습니다.
Mike Sherrill 'Cat

소프트웨어가 오류를 발견하기 위해 중단 점을 필요로하는 경우 두뇌에도 오류가 필요합니다. 이렇게하면 자신을 강요하고 떠나지 않는 것보다 더 많은 시간을 절약 할 수 있습니다.
setzamora

관련있는 값을 기록하는 로깅 기능이 종종 이런 종류의 것을 추적하는 더 좋은 방법이라는 것을 알았습니다. 변경 사항이 눈에 띄도록 깔끔한 열로 로그 줄의 서식을 지정하십시오. 이 로깅 기능을 호출 한 ID로 자주 호출하십시오. 변수 모니터링 단계보다 로그 파일을 훨씬 빠르게 검사 할 수 있습니다.
Loren Pechtel

10

디버깅은 문제를 정확히 격리하고 이해하는 것에 관한 것입니다 (수정 적용과 비교).

디버깅 할 때주의해야 할 사항은 실제로는 실제로 더 오래 걸리고 가능한 문제를 체계적으로 제거하지 않기 때문에 서로 다른 이론을 쫓고 있다는 것을 알기 시작하는 것입니다.

일반적으로 이러한 유형의 상황을 디버깅하는 가장 좋은 방법은 시스템을 작은 조각으로 나누고 각 조각을 분리하여 작동시키고 복잡한 각 요소를 하나씩 추가하여 중단 될 때까지 지루한 체계적인 접근 방식입니다. 그런 다음 정확한 문제를 격리했습니다. 이 방법은 약간 지루하고 다소 선행적인 작업이지만 복잡한 소프트웨어를 디버깅하는 동안 변수를 제거하고 두뇌를 깨끗하게 유지합니다.


5

이것들은 과거에 내가 한 일들입니다. 분명히 모든 상황에서 모든 것이 작동하지는 않습니다.

  1. 그것이 코드 일 뿐이고 어딘가에 고칠 있는 버그 (검은 마술이 아님)가 있다는 것을 깨달으십시오 .
  2. 휴식을 취하다.
  3. 코드를 매우 느리게 진행하면서 각 단계를 분석하고 코드를 이해하고 코드가 무엇을하고 있는지를 이해하고 확인하십시오.
  4. 문제를 살펴볼 두 번째 눈을 얻으십시오.
  5. 잠을 자고 내일까지 잊어 버리십시오 (머리를 비우십시오).
  6. 코드를 인쇄하고 각 줄을 분석하여 여백에 메모를하고 모든 줄의 모든 의미를 이해합니다
  7. 치명적인 버그는 아니지만 사용자가 알 필요가없는 오류를 일으키는 경우 (부끄럽지만 정직하게) 버그를 잡아서 삼켰 습니다! 위험하지 않고 원인을 찾을 수없는 경우 때로는 원인을 파악하여 사용자에게 아무 일도 발생하지 않았 음을 알리지 않습니다. 그것은 고객을위한 ROI에 관한 것이며 때로는 가치가 없습니다.
  8. 버그를 말로 쫓아 내고 죽일 것이라고 말하십시오. 때로는 도망 가기도합니다. :-)

흑 마법이 아니기 때문에 +1!
Guy Sirton

오늘날 코드에서 수행하는 모든 복잡한 종속성으로 인해 흑 마법입니다. 그러나 당신은 그것을 잘 얻을 수 있습니다 :)
Subu Sankara Subramanian

3

나는 보통 버그를 해결할 때이 방법을 사용합니다.

  1. 버그를 재현하기 위해 단계별로 좋은 단계를 만듭니다
  2. 단계별로 단순화
  3. 코드에서 버그는 어디에서 발생합니까? 어떤 기능이 관련되어 있습니까?
  4. 버그가 발생할 때 코드는 어떤 경로를 선택합니까?
  5. 위치에 초점을 맞 춥니 다. 그런 다음 오류가 발생한 지점을 정확히 찾을 때까지이 과정을 반복하십시오.
  6. 왜 이런 일이 발생합니까?

이 시점에서 문제에 초점을 맞추는 과정에서 많은 것을 배우기 때문에 무슨 일이 일어 났는지는 일반적으로 분명합니다. 또는 포럼에서 요청할 수있는 매우 집중된 질문이 있습니다.

그런 다음 문제를 해결하고 1 단계에서 만든 단계별로 버그가 수정되었는지 확인합니다.


3

이전의 모든 조언은 훌륭하며 대부분 버그 / 오류에 대한 가정을 확인한 다음 디버깅 프로세스에 따라 오류를 찾습니다 (때때로 버그 주변의 환경을 검사하고 때로는 코드에서 직접).

이 접근 방식은 선임 또는 전문 지식에 관계없이 항상 작동하지는 않습니다. 때로는 문제에 대한 또 다른 시각이 필요합니다. 문제를 검토하거나 나와 함께 세션을 디버깅 할 사람을 찾으십시오. 종종 코드를 통해 대화하면 오류가 발생할 수 있습니다.


나는 그것이 종종 저에게 효과적이라고 동의합니다.
Mike Dunlavey

1

다른 사람들이 말했듯이 1) 안정적으로 재생할 수 있으며 2) 디버거에서 발생하는 지점까지 앞으로 나아갑니다.

어떤 이유로 든 그렇게 할 수 없다면 버그를 나타내지 않는 다른 버전의 코드가 필요한 두 가지 다른 방법이 있습니다.

  1. 디버거에서 두 버전의 코드를 나란히 실행하십시오. 나쁜 사람이 좋은 사람과 다른 일을 할 때까지 계속 따라 가십시오.

  2. 좋은 버전과 나쁜 버전의 코드를 번갈아 실행합니다. 버전 간의 차이점에 대한 차이점 이나 다른 목록이 있습니다. 그런 다음 한 버전의 코드를 점차적으로 변경하여 다른 버전과 더 가깝게 일치시킵니다. 나쁜 사람이 좋아 지거나 좋은 사람이 나빠지면 나는 그 변화를 철회하고 더 작은 변화를 만듭니다. 이런 식으로 나는 버그에 집착한다. 나는 그것이 "문제의 양쪽에 도달하고 중심을 향해 노력하는"것으로 생각합니다. 이 방법에는 디버거가 필요하지 않습니다.

문제가 재현하기 어려운 경우, 나는이 때이 같은 스택 덤프로 얻을 수있는 많은 정보로 필요 않습니다 일어난다. 진단을받을 수 있는지 확인하고 문제가 발생할 때까지 기다렸다가 충분한 정보를 얻었 으면합니다.


1

주니어 프로그래머로 작업을 수행하도록 지명 된 경우 적어도 한 사람이 직접 처리 할 수 ​​있다고 생각한 사람이 있습니다.

그런 다음 상사에게 도움을 요청하기 전에 스크랩 용지, 버그 추적에 사용한 단계 / 방법 목록, 버그 진행 정도, 각 방법을 포기한 이유 및 배운 내용을 적어 두십시오. 각 시도에서. 또한 지금까지 프로젝트에 대해 배운 내용을 요약하십시오.

이 글을 모두 마쳤을 때 맹목적으로 명백해 져야 할 일이있을 수 있습니다. 그렇다면 버그를 재현하기 위해 공개 된 내용을 따르기 만하면됩니다. 그렇지 않은 경우 상사와 대화 할 수있는 근거가 있습니다. 당신이 한 일을 보여주지 않고 도움을 요청하면 그들은 당신에게 부정적인 인상을 줄 수 있습니다.

그러나 머리를 깨끗이 정리하고 주말 후에 돌아 오면 다른 사람의 도움 없이도 즉시 해결할 수 있습니다. 항상 발생합니다.


``주니어 프로그래머로 직접 작업을 수행하도록 지명 된 경우 적어도 한 사람이 직접 처리 할 수 ​​있다고 생각한 사람이 있습니다. '' 내가 일하고 있었지만, 모든 개발자는 홈 오피스를 수행 한 후에 솔루션이없는 경우 팀워크라고 불리는 경우 도움을 요청해야합니다.
mattnz

@mattnz 내가 제안하는 것은 도움을 요청하기 전에 지금까지의 노력을 문서화하고 알려진 모든 옵션이 소진되었음을 참조하십시오. 나는 이것을 무엇이라고 부를 지 모르지만, 당신이 팀워크를 언급 한 것에 대해서는 결코 논쟁하지 않았습니다.
vpit3833

나는 '... 혼자서 다룰 수있는 능력'을 지적하고 싶었다. 내가 당신이 의도 한 것보다 조금 더 강하게 해석했다는 것을 알게되어 기쁩니다.
mattnz 1

0

우리는 방법이 상당히 다르기 때문에 재생산이 얼마나 어려운지 알아야합니다. 안정적으로 재생산 된 결함의 경우 결함의 원인을 자동화하십시오. 디버거 및 디버그 추적을 사용하십시오 (추적은 경쟁 조건 유형 결함에 가장 적은 영향을 미칩니다). 체계적입니다. 한 번에 한 단계 씩, 각 단계는 더 많은 정보를 제공합니다. 놀라운 결과가 나오면 중단하고 100 % 이해 한 다음 계속하십시오. 고통스럽게 느리지 만 충분한 시간을 주면 항상 최종 결과를 얻습니다.

그것을 재현 할 수 없다면 문제가있는 것입니다. 어떻게 수정했는지 확인하십시오. 디버그 코드를 넣고 그대로 두십시오. 결국 "폐쇄 : DNR"은 유효한 옵션입니까? (재생 / 재생할 수 없음). 비즈니스에서는 결국 비용 / 이익 결정입니다.

라이브러리가 올바른 것으로 가정하지 말고 확인하십시오.

휴식을 취하고 비용 대비 수정에 대해 실용적이며 무엇보다도 다른 사람에게 옆에 앉아 도움을 청하도록 요청하십시오.


0

여기에 좋은 답변이 많이 있습니다. 다른 몇 가지 팁 :

UI는 거의 고립되어 있지 않습니다. 버그를 재현하는 데 필요한 최소한의 기능으로 테스트 프로그램을 빌드하십시오. UI가 제대로 디자인 된 경우 실패한 UI 구성 요소를 분리하고 테스트 프로그램에서 개별적으로 실행할 수 있어야합니다. 여전히 문제를 재현 할 수 있습니까? 그렇다면 UI 구조 또는 프레임 워크에 문제가있을 수 있습니다. UI 구조를 확인하십시오-특히 보이지 않는 요소를 조심하십시오. 해당 ListView를 클릭 할 때 발생하는 상황을 정확히 파악하고 응답하지 않습니다. 어떤 이벤트 핸들러가 호출됩니까? UI 프레임 워크 자체에 버그가있을 수 있음을 명심하십시오. 결론으로 ​​넘어 가지 말고 완전히 배제하지 마십시오. 빠른 테스트는 Mosync 버전을 업그레이드하고 증상이 충족되는지 확인하는 것입니다.

실패 : 테스트 프로그램에 무엇이 남아 있습니까? 남아있는 것, 특히 실행중인 스레드의 모든 구성 요소를 이해합니다. 백그라운드에서 데이터베이스 유지 관리를 수행하는 것이 있습니까? 어떤 종류의 파일 스풀러? NSA 사용자 행동 모니터링 코드? UI가 이러한 구성 요소 중 일부 (장면 뒤)에서 작동합니까? UI는 어떤 백그라운드 작업에 의존합니까?

버그를 해결하기 위해 상당한 시간을 소비해야하는 코드를 읽는 동안 버그를 가릴 수있는 나쁜 방법에주의하십시오. 구체적으로,이 중 하나라도 보입니까?

try {
    SaveTheWorld();
} catch (std::exception& ex) { /* oh it didn't work, let's just ignore it */ }

그것은 매우 열악한 연습이며, 따라서 상당히 일반적입니다 (이봐 요! 최소한 로그를 기록하기 위해 수행중인 모든 코드를 업그레이드해야합니다. 잘못된 예외 처리를 완전히 제거하십시오. 일반적으로 예외가 무엇인지 모르는 경우 처리 할 준비가되어 있지 않습니다. C 스타일 API와 상호 작용하는 경우 누락 된 오류 코드 리턴 값을 주시하고 확인하십시오. 상호 작용하는 도구에서 오류 상태 정보를 확인하고 있습니다.

테스트 프로그램이 실패를 올바르게 처리하는 방법을 살펴보면서 생성 한 로그를 읽었지만 여전히 버그를 강조하지는 않으며 조사 할 수있는 인터페이스를 찾으십시오. 덮개 아래에서 발생해야하는 네트워크 트랜잭션이 있습니까? 그렇다면 Wireshark로 치십시오. 데이터베이스 트랜잭션? 쿼리 로깅을 시도하거나 데이터베이스 서버 상태를 확인하십시오. 파일 시스템 또는 네트워크 공유가 맞습니까? 중간 파일을 확인하거나 디버거를 사용하여 I / O를 추적하십시오. 하드웨어 I / O? 모니터 및 프로브. 경험적입니다. 예상치 못한 백그라운드 작업에서 UI가 중단 될 수 있습니다.

마지막으로 : 당황하지 마십시오. 시원하게 유지하고 시도한 것을 추적하십시오. 그래도 찾을 수 없으면 비오는 날에 추적하려면 "알려진 문제"가되어야합니다. 그런 결정을 내려야한다면 그 결정을 정당화 할 수있는 많은 자료가 필요할 것입니다.


0

사물의 계획에서 재현 가능한 버그는 (상대적으로) 쉽습니다! 왜? 버그가 사라질 때까지 항상 코드를 최소한으로 해킹 한 다음 코드의 원인을 알아 내기 위해 다시 작업 할 수 있기 때문입니다. 이것이 한 가지 방법입니다. 그것은 재현 가능합니다. 당신의 통제하에 동물이 있습니다. 찌르고 실험 해 볼 수 있습니다. 원하는 경우 해부 할 수도 있습니다.

첫 번째 목표는하는 이유를 이해 버그에서 일어나는 당신의 코드입니다. 처음에 고치려고하지 마십시오. 이해 하려고 노력 하십시오. 이해하지 않고 고치려고 시도하면 해킹을 당하고 해결하더라도 기술적 부채 가 발생할 수 있습니다.

앱의 동작을 한 줄씩 살펴 봅니다. 변수 값을보십시오. 통제의 흐름을보십시오. 행동이 먼저 이해해야한다는 내용에서 행동이 어디에서 벗어 납니까? 운영 체제가 앱에 이벤트를 보내는 방법을 알고 있습니까? "블랙 박스"문제로 어려움을 겪고 있다면 컴파일 된 라이브러리 / 프레임 워크의 소스를 얻을 수 있습니까?

이 버그를 생성하지 않는 버전 관리 시스템에 커밋이 있습니까? (버전 관리를 사용하고 있지 않습니까?) 그러한 커밋이 있으면 기록에서 이진 검색을 수행하여 버그가 발생한 위치를 정확하게 찾을 수 있습니다.

목표는 (1) 이해-원인 파악 및 그 목적, (2) 앱 동작을 자세히 조사, 이해 (3) 문제를 해결하여 문제를 분리 한 다음 델타를 조사하고 이해하는 것입니다. 당신이 할 수 있도록

그러나 정말로 고착되어 있다면 몇 주 동안 앉아 있지 마십시오. 조직의 누군가에게도 알려야합니다. 당신이 특정 지점을 지나칠 수있는 곳에서 도움을 청하면, 당신이 경영진에게 당신이 진보의 장벽에 부딪쳤다 고 느끼게하는 것은 당연한 일입니다. 그러나 학습과 이해에 중점을 둔 여러 각도에서 맞으면이 문제를 해결할 수있을 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.