코드 디버깅 방법 (Nightmare 상황)


16

나는 직장에서 응용 프로그램을 디버깅하는 일을 자주합니다. 테스트 환경 및 프로덕션 환경을 포함하여 비즈니스에 배포하는 BI 응용 프로그램입니다. 이러한 제약 조건에 따라 사람들이 제안 할 수있는 앱 / 도구 / 메소드가 있는지 궁금합니다.

  1. 소프트웨어는 테스트 환경이없는 사용자 지정 타사 응용 프로그램에 의존하기 때문에 클라이언트 사이트 나 로컬에서 디버거를 사용할 수 없습니다. (편집 : 공평하게, 어떤 경우에는 로컬에서 디버깅 할 수 있습니다. 핵심 코드 만 사용하는 경우 문제가있는 코드의 대부분은 타사 특정 통신을 캡슐화하는 dll에 있습니다 : 소켓, 프로세스 파이프, 비누 호출, 핵심 코드의 동작을 변경하는 사용자 지정 논리 일반적으로 클라이언트를 구현하거나 향상시키는 동안이 영역에 새 코드를 작성합니다.)

  2. 우리 앱에는 거의 로깅이 없습니다. 단위 테스트가 없습니다.

  3. 버전 관리에는 전체 솔루션의 1 가지 버전 만 있습니다 (source safe 2005 사용). 따라서 전체 솔루션의 이전 버전을 얻을 수 없으며 개별 파일 만 가져올 수 있습니다. (누군가이 문제를 해결할 방법이 없다면).

  4. 로컬에서 재현 할 수없고 종종 테스트 환경에서 재현 할 수 없습니다 (테스트와 프로덕션이 동일한 버전이 아닐 가능성이 높음).

  5. 클라이언트가 사용중인 버전이 소스 세이프 버전과 다를 가능성이 높습니다. 개별 파일이 업데이트되어 특정 클라이언트에 대한 사용자 지정 논리가 포함되어 있기 때문입니다. 종종 다른 바이너리에 대한 변경이 필요한 바이너리에 대한 업데이트가 발생하지만 커밋이 완료되면 아무도 이에 대한 기록이나 지식이 없습니다. 다소 일반적인 오류는 클라이언트 환경에서 '함수 / 방법을 찾을 수 없음'또는 '방법 호출에 너무 많은 매개 변수가 지정되었거나 너무 적습니다.'입니다.

  6. 이것은 .net VB 솔루션입니다

  7. 클라이언트 사이트에는 소프트웨어를 설치할 수 없지만 로컬로 설치할 수는 있습니다

  8. 우리의 응용 프로그램은 매우 사용자 정의가 가능하지만 불행히도 사용자 정의 논리는 클라이언트마다 데이터베이스에 대한 사용자 정의 변경 사항을 포함하여 프론트 엔드에서 데이터 계층까지 모든 클래스와 파일에 분산되어 있습니다.

  9. 코드에는 실제로 주석이 없습니다. 아키텍처에 대한 설명서는 없습니다. API에 대한 문서가 없습니다. 우리가 가진 유일한 것은 진행 상황을 설명하는 수백 개의 이메일 체인입니다. 코드를 아는 유일한 사람은 원래 코드를 작성한 사람이지만 더 이상 개발자가 아니기 때문에 그다지 관여하지 않습니다.

그리고 당신이 말하기 전에 ... 네 알아요; 나도 쏴보고 싶어 스파게티 코드, 수백 개의 컴파일러 경고 및 REALLY를 수정 해야하는 깨진 다형성이 도움이되지는 않지만 도움이되지는 않습니다.

내가 겪는 가장 일반적인 종류의 오류는 null 참조 오류, 유효하지 않은 캐스트 및 누락 된 함수 / 기능 서명 불일치입니다. 때로는 운이 좋으며 이벤트 뷰어가 클래스, 메서드 및 예외 메시지를 기록합니다. 가장 도움이되지는 않지만 여전히 뭔가입니다. 가장 나쁜 것은 추적이없고, 스크린 샷 외에 재현 단계가없는 오류이며, 위에서 언급 한 것과 같은 일반적인 오류 메시지입니다. 때때로 그 원인을 파악할 수없고 환경이 올바르게 구성되지 않았으며 나중에 사라지도록기도하기 만 할 수도 있습니다.

나는 이것이 약간의 진창으로 벗어났다는 것을 알고 있습니다. 그러나 나는 옵션에 필사적입니다. 사용할 수있는 다른 방법 / 도구가 있습니까?


43
이력서가 있습니까?
Robert Harvey

5
"나도 쏴보고 싶다"는 +1 Source Safe 2005, 아야. 글쎄, 적어도 당신은 멋진 역사 수업에 '초점'을 두어야합니다-당신은 기본적으로 시간 여행자입니다! 당신은 "그래서 우리가 더 이상 그렇게하지 않는 이유"에 대한 신중하게 개발 된 지식의 교훈을 배울 것입니다. Godspeed, 메뚜기.
BrianH

7
요구 사항 # 1이 주어지면이 혼란을 효과적으로 디버깅 할 수있는 유일한 방법은 천리안입니다. 진지하게, 이것을 긁는 것만으로 만들 마법의 총알은 없습니다. 어떤면에서는 디버깅이 운이 좋기 때문에 약간의 압력이 가해집니다. 아니면 경영진이 운이 좋도록 명령 할 것입니까? 분명히 이것은 지속 가능하지 않으므로 다른 기회를 찾아야합니다.
Charles E. Grant

14
실제 경력 조언은 다음과 같습니다. 끔찍한 소프트웨어 엔지니어링 사례가있는 집에서 너무 오래 보내면 필연적으로 발생할 수있는 문제에 대해 나쁜 개발자가되어 경영진에 의해 비난받을 수 있습니다. 나는 거기에 있었고 다른 사람들도 가지고 있다고 확신합니다. 최선을 다하면 나쁜 개발 습관을 낳습니다.
로봇 고트

2
내가 어떻게 이러한 상황을 관리 하는가
케빈 클라인

답변:


22

로버트 하비의 조언이 가장 좋을 것이지만, 직업 조언이 주제가 아니기 때문에 어떤 대답을 할 수 있는지 알려 드리겠습니다.

당신은 가시 나무와 진흙과 초조 한 산 염소로 덮인 매우 가파른 산의 바닥에 있습니다. 쉬운 방법은 없습니다. 정상에 오르려면 한 번에 엄청난 고통을 겪어야합니다.

어떻게 작동 하는지 정확히 아는 것 같습니다 . 다른 사람이 당신을 도울 수 없다면 (다시, 직업 조언을 무시하고) 당신의 유일한 선택은 이러한 것들을 스스로 고치기 시작하는 것입니다.

첫째, 거룩한 모든 것을 위해 실제 버전 제어 시스템 에서 그 물건을 얻으십시오 . 쓰레기 더미로 잘 알려진 소스 세이프 (Source Safe)를 제외한 거의 모든 것이 있습니다. git무료이며 상당히 쉽게 설정할 수 있습니다. 과거 버전 제어 부족 문제를 해결할 수는 없지만 문제가 앞으로 계속 진행되는 것을 최소한 중지하십시오.

다음으로 로깅을 살펴보십시오. 로깅 시스템을 찾거나 최악의 경우 로깅 시스템을 작성하고 사용을 시작하십시오. 클라이언트 사이트에서도 사용할 수있는 것을 사용하십시오. 따라서 옆으로 갈 때 최소한 무언가가 있습니다.

최소한 새로운 변경 사항에 대해서는 테스트 작성을 시작하십시오.

설탕 코팅이 없습니다 : 많은 작업을 포함하지 않거나 이것을 직업의 문제로 취급하지 않는 대답은 없습니다.


나를 믿습니다. 어설 션, 가드 및 로깅을 추가하고 데이터 레이어를 다시 작성하는 것 이상을 원할 것입니다 (일반적인 구성 문제를 진단하기 위해 구성 검사기를 작성 중입니다). 불행히도 그것은 나에게 달려 있지 않습니다. 소스 안전 장치로 푸시하도록 요청을 할 수 있지만 일반적인 응답은 '귀하의 의도는 좋지만 우리가 집중해야 할 것은 아닙니다'입니다. 아아, 나는 1/2 년의 경험을 가진 주니어입니다. 나는이 산을 잠시 동안 등반 할 것이다.
Igneous01

9
@ Igneous01 솔직히 등반 할 다른 산을 찾으십시오. 다른 곳에서의 근무 조건은 완벽하지 않을 수도 있지만, 적어도 귀하가 경험하는 것보다 적어도 대부분이 더 나은 것 같습니다. 게이트 키퍼가 "이것은 우리가 집중해야 할 것이 아닙니다"로 개선을 거부하면, 결정을 내리고 실패한 정책의 결과를 얻을 것입니다. . 문제는 그들이 할 때까지 계속 고집하고 싶습니까?
cmaster-monica reinstate

6
그리고 잘못된 정책이 실패하면 관련된 모든 사람, 심지어 동의하지 않은 사람까지도 모두 나쁜 것으로 보입니다.
로봇 고트

1
예, 로깅 및 추적을 시작하십시오. 또한 문서화 및 주석 추가를 시작하십시오. 비트 단위로 모두 합산됩니다. 또한 팀이 아닌 경우에도 회사에 원래의 코더를 보유 할만큼 운이 좋다고 말합니다. 경영진이 그들에게 접근 할 수 있도록하십시오. 가능하다면 질문에 끊임없이 접근하는 것보다 약간의 문서를 작성하도록 설득하십시오.
Mawg는 모니카 복원

4
@ Igneous01 : 뛰지 마라. 이곳은 아프고 아프게 할 것입니다.
Reinstate Monica-M. Schröder

8

1) 클라이언트 사이트에서 디버거를 사용할 수 없습니다 ...

완벽하게 정상입니다.

... 또는 로컬

이제 문제입니다.

2) 우리 앱에는 거의 로깅이 없습니다.

로깅 프로덕션 디버깅입니다.

단위 테스트가 없습니다.

이런. 그러나 모두 공통입니다.

3) 버전 관리에는 전체 솔루션의 1 버전 만 있습니다.

그런 다음 버전 관리를 사용하지 않습니다.

4) 로컬에서 재생산 할 수없고, 종종 테스트 환경에서 재생산 할 수 없습니다 (테스트와 프로덕션이 동일한 버전이 아닐 가능성이 높음).

따라서 배치 된 클라이언트 환경 만 오류를 표시합니다.

이 경우, 당신은 응용 프로그램 코드에 포함 disgnostic 로깅을 필요로하는 (A) 트랩 및 [전체] 기록 [치명적인] 오류와 (b)는 추가적인 연속, 진단 생산 요구에 "최대 다이얼"할 수 유용 의를 문제를 추적합니다.

5) 클라이언트가 사용중인 버전이 소스 안전 버전과 다를 가능성이 높습니다.

다시 한 번, 버전 관리를 유리하게 사용하지 않습니다.

8) 우리의 응용 프로그램은 매우 사용자 정의

그것은 꽤 일반적입니다.

사이트 별 차이점은 버전 제어 "브랜칭"을 통해 관리해야합니다.

9) 코드에는 실제로 주석이 없습니다.

다시 말하지만, 개발자가 "자체 문서화"코드를 작성하기 때문에 너무 흔합니다.
또는 적어도 그들이 작성하는 날에 이해하는 코드.

아키텍처에 대한 설명서는 없습니다.

이런.

API에 대한 문서가 없습니다.

어머, 어머나

그리고 당신이 말하기 전에 ... 네 알아요; 나도 쏴보고 싶어

아니; 당신은이 모든 것들을 쓴 사람들을 쏘고 문서화가 불가능하고 엉망이 된 엉망을 만든 다음 새로운 목초지로 옮겼습니다.

내가 겪는 가장 일반적인 종류의 오류는 null 참조 오류, 유효하지 않은 캐스트 및 누락 된 함수 / 기능 서명 불일치입니다.

널 참조 및 유효하지 않은 캐스트는 런타임 오류입니다. 어느 정도까지는, 당신은 그것들을 기대해야하고 그들이 당신이 그것들을 얻는다는 사실은 원저자에 의한 방어 적 프로그래밍의 부족 (혹은 낙관론의 잉여)을 암시합니다.

함수 서명이 일치하지 않으면 빌드 가 손상됩니다 . 그것들은 "깨진 빌드"를 야기해야하며 절대 문 밖으로 나가지 않아야합니다!


2
"항상 코드를 관리하는 사람이 귀하의
거주지

런타임 오류는 방어 프로그래밍 부족보다 이해 부족으로 인해 더 많이 발생 합니다. 방어 프로그래밍은 코드가 작동하지 않는다는 사실을 숨기는 방법 일뿐입니다.
user253751 2018 년

1
"아키텍처에 대한 문서가 없음"은 일반적으로 "아키텍처가 없음"을 의미합니다.
gnasher729

The site-specific differences should be managed through Version Control "Branching".-이것이 최선의 방법이라고 생각하지 않습니다. 구성 파일과 기능 토글을 사용하는 것이 더 일반적이며 추론하기 쉬운 것 같습니다.
sixtyfootersdude

5

로깅부터 시작하십시오. 이것은 가장 큰 영향을 미칩니다. Log4Net 또는 이와 유사한 코드 기반으로 로깅 프레임 워크를 구현하십시오. 코드가 수행하는 작업을 기록하십시오.

디버깅은 로컬에서 가능해야합니다. 그렇지 않은 경우 심볼 파일 (PDB)을 가져 와서 타사 dll로 디버그하여 발생한 문제에 대한 완전한 그림을 얻을 수 있습니다. WINDBG와 같은 도구는 시스템이 충돌하는 경우 어떤 DLL이 문제가되는지를 가리킬 수 있습니다. 충돌이있을 때 서버가 메모리 덤프를 받도록 구성 할 수 있습니다. 기본적으로 문제가 발생했을 때 발생한 상황에 대한 스냅 샷입니다. 로컬에서 덤프를 검사하여 발생한 상황에 대한 단서를 찾을 수 있습니다. 디버깅이 불가능한 경우 가능하게하십시오. 디버그하는 데 필요한 단계를 문서화하십시오. 복잡한 시스템에서는 언젠가는 완전히 디버깅하는 데 필요한 많은 설정이 있습니다.

버그 추적 ... 하나를 사용하지 않는 경우 하나를 사용하십시오. 이것은 적절한 버전 관리 시스템을 사용하여 손에 goes니다. 기본적으로 코드의 결함 및 개정 추적을 시작하십시오. 시스템 히스토리 빌드를 시작하십시오.

정적 코드 분석을 수행하십시오. ReSharper와 같은 도구에 투자하십시오. 가능한 모든 null 참조 예외 및 기타 잘못된 코딩 방법을 신속하게 지적합니다. 몇 번의 클릭만으로 코드의 모양을 개선하고 코드 형식, 변수 이름 지정 등과 같은 지루한 항목을 자동화 할 수 있습니다. 코드를 측정하고 코드 메트릭스를 통해 리팩토링을위한 핫스팟이 어디 있는지 확인하십시오.

리 팩터 및 단위 테스트. 아마도 작성된 코드의 대부분이 테스트 할 수 없다고 가정 할 것이므로 테스트를 추가하려고하지 않을 것입니다. 모든 새로운 코드는 테스트 프로젝트를 만들고 단위 및 통합 테스트를 작성합니다. 단위 테스트에 실패하면 빌드에 실패합니다. 따라서 리팩토링 할 때 테스트가 있어야합니다. 테스트의 한 가지는 전체 애플리케이션 또는 코드베이스를로드하지 않고도 메소드를 호출하고 해당 메소드로 디버그하기위한 테스트를 작성할 수 있다는 것입니다. 문제 해결에 도움이됩니다.

필요한 부족 지식을 문서화하십시오. 코드는 자체 문서화되어야 주석이 드물게 작성되지만 많은 시스템은 "비정상적인"방식으로 작업을 수행하며 코딩 WIKI 또는 기타 유형의 비공식 저장소에서 지적합니다. 또한 코딩 표준 및 실습을 생각해보십시오. Resharper와 같은 툴셋을 통해 이러한 표준을 시행하십시오. 대부분의 코드는 표준 및 지침을 따르지 않을 것이므로 작성된 새 코드에서 표준을 구현하십시오.

당신의 새로운 이후로, 나는 이것을 의무 여행처럼 취급 할 것입니다. 6 개월에서 2 년까지 기다렸다가 계속 선택하거나 계속 진행하십시오. 전날보다 조금 나아지면서 만족을 얻으십시오.


4

먼저, 위의 모든 것 ...

일부 휴리스틱 :

  • 개발 컴퓨터에서 소스 제어를 사용하십시오. 내가 한 최고의 일이야. 우리가 가지고있는 프로젝트의 버전 관리를 대신하지는 않습니다. 이 도구는 두려움없이 실험하고 해킹하며 동시에 독립적으로 문제를 해결할 수있는 놀라운 자유를 제공하는 도구입니다. 대담하고, 조여서 배우는 자유가 있기 때문에 버전 관리를 사용하는 것이 좋습니다.
  • 주석을 추가 할 때까지 공용 인터페이스 요소의 우선 순위를 지정하여 지능을 활용하십시오. 디버그 어드벤처 중에 해독 할 때이 작업을 수행하십시오.
  • 사소한 리팩토링을 유지하십시오. 조만간 주어진 코드 덩어리에 대해 클래스 전체에서 중복 코드를 건조하는 것과 같은 큰 리팩토링을 가능하게하는 임계 질량에 도달하게됩니다.
  • 동일한 버전 제어 커밋에서 코드 재 포맷과 실제 변경 사항을 혼합하지 마십시오.
  • SOLID 원칙
    • 단일 책임을 무시하지 마십시오. 잘, 이것은 객체 지향의 약속에 이르는 길입니다 ; 이모.
    • 항상 열기 / 닫기를 무시하십시오.
    • 우리는 여기서 새로운 코드를 말하고 있지 않습니다.
    • 의도적 인 설계없이 인터페이스를 만들면 유지 관리에 방해가됩니다.
  • 리팩토링
  • 일부 코드 파일은 디버깅을 시도하기 전에 완전한 재 포맷, 변수 이름 변경 등이 필요합니다. 단위 테스트없이 Visual Studio의 리팩터링 메뉴를 사용하는 것에 대해 부끄러워하지 마십시오.
  • 잘못 놓칠 수없는 유일한 문서는 코드 파일에 있습니다.
  • 버전 관리를 받으면 VC 계획을 미리 예측하십시오. 그리고 그것을 문서화하십시오! 그리고 주요 소프트웨어 버전과 이정표를 강조하는 브랜치, 태그에 대한 명명 규칙을 제시합니다.
  • 좋은 장비를 사용하십시오
  • 고무 오리 디버깅 연습
  • 때때로 일어날 수있는 최악의 일은 그들이 당신을 해고하지 않는다는 것입니다.

편집하다

.NET의 브라운 필드 애플리케이션 개발

이 책을 사용해보십시오. 처음부터 끝까지 읽은 것이 가장 좋습니다. 이 책은 큰 그림, 가능성에 대한 생각과 전략적 및 전술적 공격 계획을 개발하는 데 도움이됩니다.

튀어 나와

가능하면 1.5 년을 유지하십시오. 당신이 경험적 진보를하고 있는지 알기에 충분히 길다. 2 년의 경험 또는 6 개월의 경험을 4 번 받고 있는지 알게 될 것입니다.

"1/2 년 경력을 가진 주니어"이기 때문에 잠재적 인 고용주가 그것을 해킹 할 수 없었기 때문에 그것을 조기에 쫓아내는 것으로 생각합니다. z, y, x를 배우고 일부 이름을 취하고 엉덩이를 찼다는 것은 한 가지입니다. 그러나 귀하의 능력에 기여할 수는 없었습니다. 다른 하나는 단순히 설명을 통해 작업, 코드, 관리 등을 파기 할 위험이 있습니다.

나는 이것을 기반으로 할 수도 있지만 내 "최고의 시간과 최악의 시간"은 문자 그대로 유지 관리 할 수없는 코드 인 첫 번째 직업이었습니다. 나는 중요한 관리자를 재 작성할 수있는 공간을 제공 한 훌륭한 감독관 (모든 나머지는 사내 사육 프로그램에서 나왔습니다)을 가졌습니다. 그 경험은 계시였습니다.

편집 종료


동일한 버전 관리 커밋에서 코드 재 포맷과 실제 변경 사항을 혼합하지 마십시오 +1-훌륭한 조언
kiwiron

0

나는 (5)가 먼저 고쳐야한다고 말합니다. 프로덕션 환경에서 어떤 코드가 실행 중인지 모르는 경우 문제를 재현하고 수정하는 안전한 방법이 없습니다. 이렇게하면 예측할 수없고 재현 할 수없는 문제가 발생할 수 있으므로 다른 변경 사항은 위험합니다.

어떤 버전의 코드와 어떤 라이브러리가 배포되었는지 알아 내기 위해 약간의 탐정 작업과 역 엔지니어링이 필요할 수 있습니다. (그리고 앞으로 배포 된 모든 코드를 소스 제어와 일치하도록 일관된 빌드 및 배포 시스템이 필요합니다.)

다양한 배포를 복제하기 위해 여러 테스트 환경을 구축해야 할 수도 있습니다. (물론 가장 간단한 해결책은 새로운 깨끗한 빌드를 만들어 어디서나 일관되게 배포하는 것이지만 이것이 불가능한 것 같습니까?)

배포 된 정확한 버전을 알고 해당 테스트 환경이있는 경우에만 코드 수정 / 개선을 시작해야합니다.

다음 우선 순위는 어디에나 배포 할 수있는 단일 코드베이스로 통합하는 것입니다. 사용자 정의로 인해 다양한 버전의 코드가 배포 된 것 같습니다. 단일 버전으로 통합 한 다음 사용자 지정 논리에 구성 스위치를 사용해야합니다.

그런 다음 디버깅을 쉽게하기 위해 코드베이스로 신중하게 개선하기 시작할 수 있습니다. 로깅을 추가하는 것이 가장 위험하지 않은 개선 일 것입니다.

자동화 된 테스트를 추가하려고하지만 처음에 테스트 용으로 설계되지 않은 프로젝트에는 단위 테스트를 추가하기가 어렵습니다. 대신 자동화 된 엔드 투 엔드 통합 테스트로 시작하는 것이 좋습니다. 이것들은 설정하기가 더 까다 롭지 만 솔루션을 다시 아키텍처로 만들 필요가 없으므로 덜 위험합니다.


0

팀의 문제를 무시하면 해결해야 할 첫 번째 문제는 프로덕션 환경에 맞는 코드를 디버깅하는 것 같습니다. 그렇지 않으면 "소스 컨트롤"에있는 코드에서 이미 수정 된 버그를 쫓을 수 있습니다. 이것이 .NET이므로 프로덕션 바이너리를 쉽게 "디 컴파일"하여 코드와 기존 코드를 비교할 수 있습니다. 쉬운 작업은 아니지만 성공하면 출시 된 버전에 태그를 지정할 수있는 더 나은 소스 제어 도구에 대한 강력한 주장입니다.


디 컴파일을 의미 할 때 IDA Pro와 같은 것을 사용하여 머신 코드를 볼 수 있습니까? 아마 아무도 그것을 사용하는 유일한 사람 일 것입니다. 왜냐하면 여기 아무도 조립을 알지 못하기 때문에 (그리고 나는 기본 사항을 알고 있습니다).
Igneous01

글쎄, 이것이 .NET이기 때문에 바이너리는 머신 코드가 아니며 CIL에 있습니다 ( en.wikipedia.org/wiki/Common_Intermediate_Language ). 이 코드는 특히 난독 처리되지 않은 경우 c # 또는 VB 코드로 매우 쉽고 정확하게 다시 변환 될 수 있습니다. 예를 들어 ( ilspy.net ) ILSpy로 시도해 볼 수 있지만 사용할 수있는 다른 도구가있을 수 있습니다.
20c
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.