코드를 가장 효과적으로 디버깅하는 방법은 무엇입니까? [닫은]


33

코드에 들어온 버그는 최소화 할 수 있지만, 프로그래머가 많은 사람들은 동의하지 않지만 프로그래머 만 있으면 완전히 제거 할 수는 없습니다 .

코드에서 오류를 감지하면이를 제거하기 위해 무엇을 할 수 있습니까? 소중한 시간을 가장 효과적으로 활용하고 시간을 절약하고 코딩에 더 많은 시간을 할애 할 수 있도록 어떻게 접근해야합니까? 또한 디버깅 할 때 무엇을 피해야합니까?

여기서는 버그 예방 에 대해 이야기하고 있지 않습니다 . 우리는 버그 나타날 때해야 할 일에 대해 이야기하고 있습니다. 이것은 넓은 분야이며 언어, 플랫폼 및 도구에 크게 의존 할 수 있습니다. 그렇다면 사고 방식 및 일반적인 방법과 같은 답변을 포함하십시오.


연결된 질문이 제거되었습니다.

1
나는 그 접근법이 실제로 간단하다고 생각합니다. 혼자 개발했다면 모든 것을 알고 있습니다. 디버깅하지 않고 버그를 수정할 수도 있습니다. 이를 염두에두고 가장 좋은 방법은 다른 것을 코딩하는 데 시간을 사용하는 것입니다. 그것에 대해 잘 아는 사람이 문제를 해결하는 방법에 대한 질문에 대답 할 수있을 때까지; 또는, 그것을 고치려는 생각이 떠오를 때까지 다른 것들을 코딩하고 휴식을 취하도록하세요. 내 생각 엔 귀하의 질문은 엔터프라이즈 팀 관리에 관한 것입니다.
물병 자리 힘

레이드라고 생각합니다. 상용, 버그 제거 스프레이. 이것은 철학적 인 질문입니까? 책은 단순한 우세에서 만들어진 것입니다 ...
ejbytes

답변:


38

디버깅에 대한 사고 방식과 태도는 아마도 가장 중요한 부분 일 것입니다. 오류를 얼마나 효과적으로 해결하고 무엇을 배울 지 결정하기 때문입니다.

Pragmatic ProgrammerCode Complete 와 같은 소프트웨어 개발의 고전은 기본적으로 동일한 접근법을 주장합니다. 모든 오류는 거의 항상 자신에 대해 배울 수있는 기회입니다 (초보자 만 컴파일러 / 컴퓨터를 먼저 비난하기 때문에).

그러니 그것을 깨뜨릴 수있는 미스터리로 취급하십시오. 그리고 우리 자신의 가정 (자신 또는 다른 사람에게)을 표현한 다음 필요에 따라 하나씩 가정을 테스트하여 미스터리를 체계적으로 수행해야합니다. 특히 모든 도구, 특히 디버거 및 자동화 된 테스트 프레임 워크를 사용합니다. 그런 다음 미스터리가 해결 된 후에도 비슷한 오류가 있는지 모든 코드를 살펴보면 더 나은 결과를 얻을 수 있습니다. 그리고 무의식적으로 오류가 다시 발생하지 않도록 자동화 된 테스트를 작성하십시오.

마지막 노트-나는 "버그"가 아닌 오류를 "오류"라고 부르는 것을 선호한다.-Dijkstra는 부정직하기 때문에 후자의 용어를 사용하는 동료들을 속였다. 우리 자신의 (조잡한) 생각 때문에 거기에있는 대신 보는 것 : http://www.cs.utexas.edu/users/EWD/transcriptions/EWD10xx/EWD1036.html

예를 들어 버그를 더 이상 버그라고 부르지 않고 오류라고 부르면 언어를 정리할 수 있습니다. 그것은 그것이 속한 곳의 비난을 제곱하기 때문에 훨씬 더 정직합니다. 오류를 일으킨 프로그래머와 함께. 프로그래머가보고 있지 않은 동안 악의적으로 몰래 들어온 버그의 애니 메틱 은유는 그 오류가 프로그래머 자신의 창작물이라는 것을 위장하기 때문에 지적으로 부정직하다. 이 간단한 어휘 변경의 좋은 점은 그것이 매우 심오한 영향을 미친다는 것입니다. 전에는 버그가 하나만있는 프로그램이 "거의"옳았지만, 나중에 오류가있는 프로그램은 "잘못된"것입니다. 오류).


7
사실 나는 "오류"보다는 "오류"라는 용어를 좋아한다. "오류를 일으킨 프로그래머"에게 책임이 있기 때문이 아니라, 그것이 프로그래머의 잘못 이 아닐 수도 있다는 것이 분명하기 때문이다 . 나에게 "버그"는 코드의 오류를 의미한다. "오류"는 어딘가에 오류가 있음을 의미합니다 . 아마도 코드에서, 환경 설정에서, 아마도 요구 사항에서. 상사가 "버그 목록"을 가지고있을 때 문제의 절반이 요구 사항이 변경 될 때 불안해합니다. 그것을 작업 목록이라고 부르십시오, ferchrissakes!
Carson63000

2
+1 "모든 오류는 거의 항상 자신에 대해 배울 수있는 기회입니다 (초보자 만 컴파일러 / 컴퓨터를 비난하기 때문에)"
Md Mahbubur Rahman

"버그"라는 용어의 역사를 알고 있습니까? 소프트웨어 개발에 사용됩니다. 물론 오늘날에는이 문제가 없지만 실제로 프로그래머가 알지 못하는 컴퓨터 하드웨어에 버그가 발생하여 문제가 발생했습니다. 누군가 나를 교정하지 않으려면 에디슨이 나방 사건이 있기 훨씬 전에이 용어를 사용했다는 것을 알고 있습니다. 참조 computerworld.com/article/2515435/app-development/...en.wikipedia.org/wiki/Software_bug#Etymology
THREED

물론 @threed. 그러나 꽤 오랫동안 곤충은 대부분의 소프트웨어 오류를 일으키지 않았습니다.
limist

16
  1. 테스트를 작성하십시오. 테스트는 버그를 예방하는 데 탁월 할뿐 아니라 (제 경험상 TDD가 거의 모든 사소하고 어리석은 버그를 제거함) 디버깅에 큰 도움이됩니다. 테스트를 수행하면 디자인이 모듈식이되므로 문제를보다 쉽게 ​​격리하고 복제 할 수 있습니다. 또한 환경을 제어하므로 놀라움이 훨씬 줄어 듭니다. 또한 테스트 사례가 실패하면 자신을 괴롭히는 행동 의 실제 원인을 파악했는지를 합리적으로 확신 할 수 있습니다 .

  2. 디버거 사용 방법에 대해 알아보십시오. print문은 어느 정도 수준에서는 합리적으로 작동하지만 대부분의 경우 디버거가 매우 유용합니다 (사용 방법을 알고 나면 print문 보다 훨씬 편안 합니다).

  3. 고무 오리 인 경우에도 문제에 대해 누군가에게 이야기하십시오 . 당신이하고있는 문제를 말로 표현하도록 강요하는 것은 실제로 기적입니다.

  4. 자신에게 시간 제한을 줘. 예를 들어 45 분 후에도 아무데도 갈 수 없다고 생각되면 잠시 동안 다른 작업으로 전환하십시오. 버그로 돌아 가면 이전에는 고려하지 않았던 다른 가능한 솔루션을 볼 수 있기를 바랍니다.


2
"1로 말하고있는 문제를 말로 표현하도록 강요하면 실제로 기적이됩니다."
Md Mahbubur Rahman

그리고 (1)에 추가하기 위해 코드에서 볼 수있는 거의 모든 버그는 테스트 스위트에 버그가 있거나 적어도 생략되었음을 나타냅니다. 동시에 두 문제를 해결하고 문제를 해결했다는 사실을 입증 할뿐만 아니라 문제가 다시 발생하지 않도록 안전합니다.
Julia Hayward

3

버그의 재생산도 중요하다고 생각합니다. 버그를 재현 한 모든 사례를 나열한 다음 버그 수정이 해당 사례를 모두 포함하는지 확인할 수 있습니다.


3

과학적 방법을 적용하여 버그를 분리하고 해결하는 방법부터 델타 디버깅에 이르기까지 다양한 버그를 찾기위한 전략을 설명하는 Why Programs Fail 이라는 주제에 대해 읽은 훌륭한 책이 있습니다. 이 책의 또 다른 흥미로운 부분은 '버그'라는 용어가 없어진다는 것입니다. Zeller의 접근 방식은 다음과 같습니다.

(1) 프로그래머가 코드에 결함을 만듭니다. (2) 결함으로 인해 감염이 발생합니다. (3) 감염이 전파됩니다. (4) 감염이 실패합니다.

디버깅 기술을 향상 시키려면이 책을 적극 권장합니다.

내 개인적인 경험에서, 나는 우리의 응용 프로그램에서 많은 버그를 발견했지만 경영진은 단순히 새로운 기능을 얻기 위해 우리를 계속 압박합니다. "우리는이 버그를 직접 발견했으며 클라이언트가 아직 눈치 채지 못했을 때까지 그대로 두십시오."라고 자주 들었습니다. 버그를 수정하는 데 능동적으로 대처하는 것이 반응이 좋지 않다고 생각합니다. 실제로 문제를 해결해야 할 시점에 해결해야 할 다른 문제가 있고 더 많은 기능 관리가 문을 최대한 빨리 열고 싶어서 악순환으로 많은 스트레스와 화상을 입을 수 있으며 궁극적으로 결함이 제거 된 시스템입니다.

의사 소통은 버그가 발견 될 때 또 다른 요소입니다. 이메일을 보내거나 버그 트래커에 문서화하는 것은 모두 훌륭하지만 내 경험상 다른 개발자도 비슷한 버그를 발견하고 코드를 수정하기 위해 넣은 솔루션을 재사용하는 대신 (그들이 잊어 버린 것처럼) ), 그들은 자신의 버전을 추가하므로 코드에 5 가지 솔루션이 있으며 결과적으로 더 부풀어지고 혼란스럽게 보입니다. 따라서 버그를 수정하는 경우 일부 사람들이 수정 사항을 검토하고 비슷한 것을 수정하고이를 처리하기위한 좋은 전략을 찾은 경우 피드백을 제공하십시오.

limist 는 버그 수정에 관한 흥미로운 자료를 가지고 있는 Pragmatic Programmer 라는 책을 언급했습니다 . 이전 단락에서 제시 한 예를 사용하여 깨진 과부의 비유가 사용되는 Software Entrophy를 살펴 보겠습니다 . 깨진 창문이 두 개가 많으면, 사전에 자세를 취하지 않으면 팀이 창문을 고치는 것에 냉담 할 수 있습니다.


"우리는이 버그를 직접 발견했으며 클라이언트가 아직 눈치 채지 못 했으므로 너무 많이 들릴 때까지 그대로 두십시오"라고 들었습니다. 그리고 현장 방문을 갔을 때 종종 고객 알아 차 렸지만보고하지 않았습니다. 때때로 그들은 고쳐지지 않을 것이기 때문에 아무런 의미가 없다고 생각하기 때문에, 때로는 경쟁사의 대체물을보고 있기 때문에, 때로는 (올바르거나 잘못) "음, 그것은 어쨌든 모든 쓰레기 더미입니다".
Julia Hayward

@JuliaHayward-대부분의 경우에 해당하지만 고객의 상황에 따라 고객은 기능에 만족할 수 있고 실제로 어떤 일이 일어나고 있는지에 대해 걱정하지 않아도됩니다. 클라이언트가 추가 기능을 요구할 때 문제가 드러나기 시작하고 앱을 다국어, 모바일 호환 blah blah로 만드는 것과 같은 다른 개선 사항을 추가해야합니다. 가지고있는 것을보고 벽의 모든 균열을 확인하십시오.
황량한 행성

소프트웨어 디자인, 테스트 및 원활한 의사 소통에 관한 전 세계의 모든 책과 작업중인 많은 제품이 엄청나게 엉망임을 보여줍니다. 옳은 것을 알고 있음에도 불구하고 스트레스와 비현실적인 마감일 (이미 엉망인 코드에 직면)은 코드가 상태에있는 이유의 원인입니다. 나는 그것에 대한 답을 얻지 못했다. 나는 사무실에서 신음하는 얼굴로 꽤 구별된다. **** 코드를 건강하게 유지하고 개발 프로세스를 매끄럽게 유지하기 위해 발로 차고 비명을 지르지 만 때로는 팀이 함께 잘 결합하십시오.
황량한 행성

3

버그, 오류, 문제, 결함-무엇을 호출하든 큰 차이는 없습니다. 내가 익숙한 것이기 때문에 문제를 고수 할 것입니다.

  1. 문제에 대한 인식이 무엇인지 파악하십시오. 고객의 'Bob이 아직 시스템에 없습니다'에서 'Bob에 대한 사용자 레코드를 작성하려고하면 Bob이 아직 중복 키 예외로 실패 함'으로 변환하십시오. 거기에'
  2. 그것이 실제로 문제이거나 오해인지 알아냅니다 (실제로 Bob은 거기에 없으며 Bob이라는 사람은 없으며 삽입도 작동해야합니다).
  3. 'Bob'사용자 레코드가있는 시스템에 사용자 레코드 'Bob'이 삽입되면 예외가 발생합니다 '와 같이 문제를 재현하기 위해 수행 할 수있는 최소한의 안정적인 단계를 시도하십시오.
  4. 이것은 가능한 테스트입니다. 가능하면 반복해서 실행할 수있는 자동화 된 테스트 하네스에 넣으십시오. 이는 디버깅 할 때 매우 중요합니다. 특정 문제가 나중에 다시 나타나지 않도록 테스트 스위트의 일부로 만들 수도 있습니다.
  5. 디버거를 꺼내고 중단 점을 시작하십시오. 테스트를 실행할 때 코드 경로를 파악하고 무엇이 잘못되었는지 식별하십시오. 그렇게하는 동안 가능한 한 좁은 단위 테스트를 통해 테스트를 세분화 할 수도 있습니다.
  6. 문제를 해결하고 테스트 통과를 확인하십시오.
  7. 고객이 설명한 원래 문제도 수정되었는지 확인하십시오 (매우 중요합니다. 문제의 일부만 수정했을 수도 있습니다). 프로그램의 다른 측면에서 회귀를 도입하지 않았는지 확인하십시오.

코드에 익숙하거나 문제 나 수정이 명백한 경우 해당 단계 중 일부를 건너 뛸 수 있습니다.

소중한 시간을 가장 효과적으로 활용하고 시간을 절약하고 코딩에 더 많은 시간을 할애 할 수 있도록 어떻게 접근해야합니까?

새로운 코드를 작성하는 것이 고품질의 작업 프로그램을 보유하는 것보다 가치가 있다는 것을 암시하므로 문제가 있습니다. 문제를 해결하는 데 가능한 한 효과적이라는 데 아무런 문제가 없지만 프로그램에 코드를 추가하는 것만으로도 더 나아지는 것은 아닙니다.


이것은 최고의 답변입니다 IMO
marcusshep

3

나는 대부분의 다른 답변을 좋아하지만 여기에 어떤 일을하기 전에해야 할 일에 대한 팁이 있습니다. beaucoup de time을 절약 할 수 있습니다.

  1. 실제로 버그가 있는지 확인하십시오. 버그는 항상 시스템 동작과 요구 사항의 차이입니다. 테스터는 예상 된 행동과 실제 행동을 분명히 할 수 있어야합니다. 그가 예상되는 행동에 대한 지원을 제공 할 수 없다면, 요구 사항이없고 버그가 없습니다. 단지 누군가의 의견 일뿐입니다. 다시 보내

  2. 예상되는 동작이 잘못되었을 가능성을 고려하십시오. 이는 요구 사항을 잘못 해석했기 때문일 수 있습니다. 요구 사항 자체의 결함 (자세한 요구 사항과 비즈니스 요구 사항 사이의 델타)으로 인한 것일 수도 있습니다. 이것들을 다시 보낼 수도 있습니다.

  3. 문제를 해결하십시오. 경험만이 가장 빠른 방법을 가르쳐 줄 것입니다. 일부 사람들은 내장으로 거의 할 수 있습니다. 하나의 기본 접근법은 다른 모든 것을 일정하게 유지하면서 한 가지를 바꾸는 것입니다 (다른 환경에서 문제가 발생합니까? 다른 브라우저에서? 다른 테스트 영역에서? 다른 시간대에 다른가?) 또 다른 접근법은 스택 덤프를 보는 것입니다. 오류 메시지-때때로 시스템의 어떤 구성 요소가 원래의 오류를 일으킨 형식을 알 수 있습니다 (예를 들어 독일어 인 경우 베를린에서 작업하는 타사를 비난 할 수 있습니다).

  4. 협업하는 두 시스템으로 범위를 좁힌 경우 트래픽 모니터 또는 로그 파일을 통해 두 시스템 간의 메시지를 검사하고 스펙에 따라 작동하는 시스템과 그렇지 않은 시스템을 판별하십시오. 시나리오에 둘 이상의 시스템이있는 경우 쌍별 검사를 수행하고 애플리케이션 스택을 "다운"하는 방식으로 작업 할 수 있습니다.

  5. 문제를 격리하는 것이 매우 중요한 이유는 문제가 사용자가 제어 할 수있는 코드 (예 : 타사 시스템 또는 환경)의 결함으로 인한 것이 아니기 때문에 해당 당사자가 가능한 한 빨리 인수하도록하려는 것입니다. . 이는 작업 시간을 단축하고 가능한 빨리 짧은 시간 안에 해상도를 얻을 수 있도록 즉시 작업을 수행 할 수 있도록하기위한 것입니다. 다른 사람의 웹 서비스에 실제로 문제가 있음을 찾기 위해 10 일 동안 만 문제를 해결하고 싶지 않습니다.

  6. 실제로 결함이 있고 그것이 실제로 제어하는 ​​코드에 있다고 판단한 경우, 마지막으로 "잘 알려진"빌드를 찾고 소스 제어 로그에서 문제점을 유발했을 수있는 변경 사항을 검사하여 문제점을 더 분리 할 수 ​​있습니다. 이것은 많은 시간을 절약 할 수 있습니다.

  7. 소스 컨트롤에서 알아낼 수 없다면 이제 디버거를 연결하고 코드를 통해 알아낼 시간입니다. 어쨌든 지금은 문제에 대한 좋은 아이디어가 있습니다.

버그의 위치를 ​​알고 수정을 생각할 수 있으면 다음과 같이 수정하는 좋은 절차가 있습니다.

  1. 문제를 재현하고 실패하는 단위 테스트를 작성하십시오.

  2. 단위 테스트를 수정하지 않고 애플리케이션 코드를 수정하여 통과시킵니다.

  3. 회귀를 방지 / 감지하기 위해 단위 테스트를 테스트 스위트에 유지하십시오.


1

내가하는 방법은 다음과 같습니다.

  1. 문제를 찾을 때마다 같은 방법을 사용하십시오. 이렇게하면 오류에 대한 반응 시간이 향상됩니다.
  2. 가장 좋은 방법은 아마도 코드를 읽는 것입니다. 코드에서 모든 정보를 사용할 수 있기 때문입니다. 정확한 자세와 모든 세부 사항을 이해하는 능력을 찾는 효율적인 방법이 필요합니다.
  3. 디버깅은 매우 느리며 프로그래머가 컴퓨터가 asm 명령어를 실행하는 방법을 아직 이해하지 못하거나 콜 스택 및 기본 항목을 이해할 수없는 경우에만 필요합니다
  4. 함수 프로토 타입을 사용하여 프로그램의 동작에 대한 추론과 같은 증명 기술을 개발하십시오. 올바른 위치를 더 빨리 찾는 데 도움이됩니다

1

코드에서 오류를 감지하면이를 제거하기 위해 무엇을 할 수 있습니까? 소중한 시간을 가장 효과적으로 활용하고 시간을 절약하고 코딩에 더 많은 시간을 할애 할 수 있도록 어떻게 접근해야합니까? 또한 디버깅 할 때 무엇을 피해야합니까?

프로덕션 환경에 있다고 가정하면 다음과 같이해야합니다.

  1. "오류"를 올바르게 설명하고 발생하는 이벤트를 식별하십시오.

  2. "오류"가 코드 오류인지 또는 사양 오류인지 확인하십시오. 예를 들어, 1 자의 이름을 입력하면 일부 시스템에서는 오류로 간주되지만 다른 시스템에서는 허용되는 동작으로 간주 될 수 있습니다. 때때로 사용자는 문제라고 생각하는 오류를보고하지만 시스템의 동작에 대한 사용자의 기대는 요구 사항의 일부가 아닙니다.

  3. 오류가 있고 오류가 코드로 인한 것으로 판명 된 경우 오류를 방지하기 위해 수정해야하는 코드 조각을 결정할 수 있습니다. 또한 현재 데이터 및 향후 시스템 운영에 대한 동작의 영향을 검사하십시오 (코드 및 데이터에 대한 영향 분석).

  4. 이 시점에서 버그를 해결하기 위해 얼마나 많은 리소스가 소비 될지 추정 할 수 있습니다. 곧 수정되거나 다가오는 소프트웨어 릴리스 내에서 수정을 예약 할 수 있습니다. 이는 최종 사용자가 수정 비용을 기꺼이 지불하는지 여부에 따라 다릅니다. 또한 사용 가능한 다른 옵션을 평가하여 오류를 수정해야합니다. 여러 가지 방법이있을 수 있습니다. 상황에 가장 적합한 접근 방식을 선택해야합니다.

  5. 이 버그가 발생한 원인 (요구 사항, 코딩, 테스트 등)을 분석하십시오. 조건이 다시 발생하지 않도록하는 프로세스를 시행하십시오.

  6. 에피소드를 적절히 기록하십시오.

  7. 수정 사항 (또는 새 버전)을 릴리스하십시오.

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