정적 분석의 함정을 피하는 방법


17

나는 적어도 종이에서 Joel Test에서 11 점을받는 회사에서 일하고 있습니다.

그러나 실제로는 예상 한 것만 큼 효과가 없으며 프로젝트는 반년 동안 DEFCON 1 에있었습니다. 자, 대부분의 동료들은 일요일 오후 6시에 집으로 돌아갈 수 있다면 행복합니다.

작동하지 않는 것으로 충격을받은 명백한 모범 사례 중 하나는 정적 분석 도구를 사용하는 것입니다. 이 프로젝트는 gcc -Wall 경고와 독점적이고 매우 비싼 "C / C ++" 도구를 추적 합니다.

Gcc 경고는 실제 (대부분의 경우 공격적이지 않은) 버그를 가리 키지 않는 것보다 자주 발생합니다.

그러나 독점 도구는 암시 적 캐스트 및 문자열 리터럴의 크기와 같은 항목을 나열합니다. 암시 적 캐스트도 스타일북에 블랙리스트에 올립니다.

표준 관행은 사람들이 모든 단일 경고를 종료하도록 압력을받는 것입니다. 여기에는 주로 오 탐지 경고가 제외되지만 문제는 아닙니다.

결과는 다음과 같습니다.

  1. 사람들은 프로세스에서 실제로 문제가되는 유형 불일치를 숨기는 모든 rvalue 및 모든 인수에 유형 캐스트를 추가합니다.
  2. 사람들은 하나의 버그로 소개하거나 다른 문제가있는 언어 기능을 사용합니다 (크기 대신에 strlen, strcpy 대신에 strncpy 등).
  3. 경고는 소리가 나지 않습니다.
  4. 버그 리포트가 시작됩니다.

요점은 원래 코드가 작동하고 언어 능력 내에서 안전하게 게임을하는 사람들이 작성하고 수정 한 것이 아니라는 것입니다.

이제이 회사를 구할 수 있다고 생각하지 않습니다. 그러나 "프로" 도구 를 사용하는 것이 더 좋고, 바람직하게 작동하는 방법이 있는지, 또는 내가 미래에 결정을 내리는 경우에 대비하여 완전히 사용하지 않아야 하는지를 알고 싶습니다.

모든 프로그래머가 실수를 할 수없는 천재라고 가정하지 않는 솔루션. 글쎄, 그렇다면 도구를 처음 사용할 필요가 없기 때문입니다.


1
참고 사항 :«-Wall»외에 GCC에는«-Wextra»옵션과 두 가지 메타 옵션에 어떤 이유로 든 포함되지 않은 더 많은 경고가 있습니다. 자세한 내용은 문서 를 참조하십시오. 일반적으로 모든 옵션은 메타 옵션에 의해 활성화 된 경우 언급됩니다. 따라서 활성화되지 않은 모든 것을 찾으려면«-Wall»및«-Wextra»라는 단어를 문서 전체에 강조 표시하고 아직 사용되지 않은 것을 볼 수 있습니다.
Hi-Angel

또한 GCC가«-Wextra»를«-Wall»에 많이 포함시키지 않았다고 생각합니다. 이 플래그들 중 일부는 매우 유용합니다 . 적어도 이러한 경고는 몇 시간의 디버깅에서 벗어날 수 있습니다.
Hi-Angel

1
아무도 답변에 코드 리뷰를 언급하지 않은 것에 놀랐습니다. 나를 위해, 어떤 엉터리 해킹에
빠져들

답변:


16

그러나 실제로는 예상 한 것만 큼 효과가 없으며 프로젝트는 반년 동안 DEFCON 1에있었습니다. 자, 대부분의 동료들은 일요일 오후 6시에 집으로 돌아갈 수 있다면 행복합니다.

이것은 확실히 당신의 문제의 좋은 덩어리입니다. 소프트웨어 엔지니어는 주당 40 시간 이상 생산적으로 일할 수 없습니다. 그 이상으로 올라가면 일주일에 80 시간을 일하더라도 프로젝트에 가치가 거의없는 지점까지 일할 수있는 능력이 심각하게 손상되며 때로는 팀이 더 많은 오류를 가져 오기 때문에 프로젝트가 회귀 할 수도 있습니다 그들은 고칠 수 있습니다. 반년 동안 주당 60 시간 이상을 수행 한 경우, 전체 팀이 긴 휴식을 취하고 주당 40 시간에 다시 방문해야합니다. 키보드를 너무 많이 사용하기 때문에 키보드를 강타 할 수없는 인력으로는 아무것도 해결할 수 없습니다 .

그러나 독점 도구는 암시 적 캐스트 및 문자열 리터럴의 크기와 같은 항목을 나열합니다. 암시 적 캐스트도 스타일북에 블랙리스트에 올립니다.

도구를 완전히 떨어 뜨리거나 재구성 / 교체해야합니다. 모든 암시 적 캐스트에 대한 경고는 누구나 처리하기에는 너무 많습니다.


주당 약 40 시간의 연구에 대한 참고 자료를 제공해 주시겠습니까?

11
여기여기 , 초보자를위한 것입니다. 일주일에 40 시간을 초과하여 생산적인 작업을 수행 할 수 없다는 것이 매우 잘 문서화되어 있습니다. 간단한 Google에서 기사를 많이 찾을 수 있습니다.
DeadMG

5
두 가지 작지만 IMHO 중요한 수정 사항 : 주당 40 시간 제한은 대략적인 평균값이며 규칙은 장기간에만 적용됩니다. 팀이 중요한 마감일 이전에 추가 시간을 투자 한 다음 나중에 복구 할 수도 있습니다 (일부 며칠이 걸릴 수도 있음). 또한 한도는 사람마다 다르며 시간이 지남에 따라 일부는 문제없이 일주일에 43 시간을 일할 수 있고, 다른 사람은 35 명만 일할 수 있으며, 다른 사람보다 몇 주 동안 더 생산적입니다. 그러나 2 주 이상 연속으로 초과 근무를하는 것은 심각한 문제를 야기 할 것입니다.
Péter Török

13

나는 적어도 종이에서 Joel Test에서 11 점을받는 회사에서 일하고 있습니다.

이 테스트는 소프트웨어 회사와 약간 관련이 있습니다. 나는 그것에 대한 과대 광고를 이해하지 못합니다. 12 점을 획득해도 여전히 100 % 불량 프로그래머가 있습니다. 사람들은 도구보다 훨씬 더 중요합니다.

그러나 독점 도구는 암시 적 캐스트 및 문자열 리터럴의 크기와 같은 항목을 나열합니다. 암시 적 캐스트도 스타일북에 블랙리스트에 올립니다. 표준 관행은 사람들이 모든 단일 경고를 종료하도록 압력을받는 것입니다. 여기에는 주로 오 탐지 경고가 제외되지만 문제는 아닙니다.

이것은 모든 정적 분석기에서 가장 큰 문제입니다. 오 탐지가 너무 많습니다. 이를 처리 하는 유일한 방법 은 도구가 특정 문제에 대해 경고하도록 설정된 이유 를 자세히 배우는 것입니다 . 그래야만 경고가 거짓인지 아닌지에 대한 자격을 갖춘 가정을 할 수 있습니다.

암시 적 유형 캐스트의 특정 캐스트의 경우 C 언어의 두 가지 (모 론적) 암시 적 유형 승격 규칙으로 인해 C 언어의 매우 일반적이고 미묘하고 위험한 버그가 있습니다. 공식적으로 정수 승격 규칙일반적인 산술 변환 . 모든 전문 C 프로그래머 10 명 중 1 명 미만이이 두 가지 규칙의 역할과 그렇지 않은 부분을 설명 할 수 있다고 생각합니다. 그러나 이러한 규칙은 매우 기본적이며 일반 C 프로그램의 행 사이에 수천 번 적용됩니다.

MISRA-C 표준은 이러한 위험한 암시 적 변환 규칙을 설명하기 위해 전체 장을 다루고 암시 적 변환으로 인한 버그를 피하는 방법에 대해 상당히 복잡한 수많은 규칙을 추가했습니다. 이것은 시장의 모든 정적 분석기에 상당한 영향을 미쳤습니다.

나는 C 프로그래머가 MISRA-C 챕터를 읽거나 최소한 Google에서 언급 한 두 가지 프로모션 규칙을 읽고 가능한 한 많이 읽도록 권장합니다. 이 규칙에 대해 알아야 할 모든 것을 알고 있으면 정적 분석기 만 무시할 수 있습니다.

이제이 회사를 구할 수 있다고 생각하지 않습니다. 그러나 "프로"도구를 사용하는 것이 더 좋고, 바람직하게 작동하는 방법이 있는지, 또는 내가 미래에 결정을 내리는 경우에 대비하여 완전히 사용하지 않아야 하는지를 알고 싶습니다.

모든 프로그래머가 실수를 할 수없는 천재라고 가정하지 않는 솔루션. 글쎄, 그렇다면 도구를 처음 사용할 필요가 없기 때문입니다.

그 주위에 쉬운 방법은 없습니다. 실제 문제는 실제로 도구가 아니라 모호한 C 언어입니다. 한 눈에 쉬운 언어 인 것 같지만, 줄 사이에는 많은 비논리적이고 이상한 메커니즘이 있습니다. 또한 언어에는 수백 가지의 정의되지 않은 / 지정되지 않은 / impl. 특정 동작이 있습니다. 그들 대부분은 배우고 피해야합니다.

따라서 이러한 모호한 경고를 모두 이해하는 베테랑 C 프로그래머가되거나 최소한 한 명 이상의 팀원이어야합니다. 팀에 베테랑이없는 다수의 주니어 프로그래머 만 고용하는 회사는 이러한 도구를 사용해서는 안되며 무결성이 높은 소프트웨어 개발을 수행해서는 안됩니다.


처음부터 소금 한 덩어리로 테스트를했지만 프로그래머를 테스트하는 도구가 아니라 고용주를 테스트하는 도구입니다. "돈을 지불 할 수있는 최고의 도구"로 적절한 동료를 포함시킬 수있을 것 같습니다. 그리고 나는 당신의 대답을 받아 SA 도구를 버리고 더 잘 고용하고 훈련합니다. 전자가 공통 분모 인 것 같습니다.

@qpr 고용주를 테스트하는 것이 아니라 소프트웨어 개발에 돈을 쓰려는 고용주의 의지입니다. 채용 절차, 기업 목표, 시장 지식 등은 언급되지 않습니다. 대부분의 "IT 버블"회사들은이 테스트에서 12 점을 낼 것이라고 생각합니다. 경영진은 어떤 제품이 개발되고 있는지 또는 전혀 시장이 있는지조차 모릅니다.

4

문제 해결 방법을 묻고 있는지 또는 처음에 문제를 피할 수 있었는지 확실하지 않습니다. 나는 후자를 가정하고 있습니다.

버그를 감지하고 피하는 주요 수단으로 정적 분석에 의존 한 것 같습니다. 아마도 단위 테스트와 메모리 검사기와 같은 동적 도구에 더 집중하는 것이 좋을 것입니다.

특히 오 탐지를 억제 할 수없는 경우 많은 오 탐지를 생성하는 도구를 사용하는 것은 좋지 않습니다. 피곤하거나 과로 한 (또는 게으른) 프로그래머가 경고를 없애기 위해 "수정"을하도록 권장합니다. 선택적으로 오탐 (예 : 주석)을 억제하거나 규칙 세트를 조정할 수없는 경우 더 나은 도구가 필요합니다. 또는 최소한 사용하지 않는 것이 좋습니다.

사람들이 부주의하고 /하거나 과로로 인해 실수를하는 데 문제가있는 것 같습니다. 코드 검토에 더 많은 시간과 노력을 기울 였을 것입니다. 이것은 프로그래머가 천재가 아니라는 당신의 관찰을 직접적으로 해결합니다.

마지막으로, 비현실적인 마감일, 가난한 사람들의 자원 조달 및 / 또는 변화하는 요구 사항으로 인해 어려움을 겪고있는 것 같습니다. 이것은 경영상의 문제이며 그 수준에서 해결되어야합니다. 그렇지 않으면 프로젝트 실패의 위험이 상당히 높아지고 직원의 생산성과 사기에 대한 장기적인 손상이 있습니다.


3

user29079의 탁월한 답변 외에도 C 언어의 결함을 하나 더 추가하여 문제를 추가하고 싶습니다. Java로 넘어갈 때까지이 결함을 알지 못했습니다.

경고의 목적은 작가와 장래의 독자들에게 비린내가 있다는 사실을 알리는 것입니다. 개념적으로는 완벽하게 괜찮습니다. 경고를 많이할수록 비린내가 많은 것을 발견 할 수 있습니다.

무엇 죽은 잘못 , 꼬추 비린내가 매일 조금, 모든 비용에 고정되어야한다는 개념입니다 코드를 변경하여이 . 이것이 OP가 설명하는 문제를 일으킨 원인입니다. 제대로 작동하는 코드를 변경하여 급하게 경고를 보내려는 botched 시도.

동시에, 우리는 코드가 컴파일 할 때마다 수백 개의 경고를 흘리는 것을 원하지 않습니다. 곧 경고는 의미가 없어지고 더 이상 새로운 경고에주의를 기울이지 않기 때문입니다.

그래서 이것은 목표가 상충되는 것처럼 보입니다. 모순.

이 겉보기 불가능한 임시에 대한 아주 좋은 해결책은 진술에 따라 진술에 따라 특정 경고를 선택적으로 억제 할 수 있으므로 우리가 실제로 무엇을하고 있는지 알지 못한다는 것을 정확하게 표시하고 싶은 곳에서 정확하게 경고 할 수 있도록하는 것입니다 코드를 변경해야합니다.

자바에는 @SuppressWarnings( "" )주석 이 달린 멋진 해결책이 있습니다. 예를 들어 Java에서 소위 검사되지 않은 변환 을 수행하는 경우 컴파일러는이를 경고하기 위해 경고를 발행하고 검사 한 후 이것이 수행중인 작업을 알고있는 경우 중 하나 이상이라고 판단합니다. 그래서 당신은 함께 기분을 상하게 문 앞에 @SuppressWarnings( "unchecked" )영향을 주석 바로 다음에 문을, 당신은 당신의 인생을 진행합니다.

따라서 경고가 사라지고 코드는 변경되지 않고 구문 강조 표시로 녹색으로 표시된 억제 주석이 거기에 표시되어 iffy 변환이 발생한다는 사실을 문서화하지만 저자는 약속합니다. (*) 모든 사람이 행복하다.

Java에서는 @SuppressWarnings()특정 매개 변수에서만 발생할 수있는 특정 경고를 비활성화 하기 위해 개별 매개 변수 앞에을 함수에 붙일 수 있습니다.

그러나 내가 아는 한 C는 명령문에 대한 경고를 선택적으로 억제하는 표준 메커니즘을 지원하지 않았으며 자체 독점 메커니즘을 구현 한 특정 컴파일러는 예를 들어 #pragma warning (nnn:N)Microsoft C의 지시문과 같이 엄격한 방식으로 그렇게했습니다 . 둘 다 억제하기 위해 하나의 명령문에 대한 경고를 지시어의 두 줄 필요가 있다는 것입니다 그리고 그 경고가 따르는 것이 제표를 사용할 수 둡니다. 따라서 C 프로그래머는이 특정 명령문에 대한이 특정 경고가 괜찮다는 것을 알더라도 개별 명령문을 기반으로 경고를 억제하는 습관을 들이지 않을 것입니다.


(*) 누군가 당신이 이것을 허락한다면, 집안에있는 모든 프로그래머는 아무런 생각도하지 않고 경고를 억제 할 것이라고 주장 할지도 모릅니다. 이에 대한 답은 프로그래머가 자신의 업무를 더 잘 수행하도록 돕기 위해 가능한 모든 것을 할 수 있지만 적극적으로 방해하는 결정을 내릴 수있는 방법은 없습니다.


다시 말해, 모든 마지막 경고를 제거하기 위해 소스 를 변경하는 것이 모범 사례의 핵심이지만, 컴파일 가능한 코드를 변경 하는 것은 정당한 이유없이 간단하게 올바른 코드를 제거하므로 불가능합니다. 좋은 구별.
Nathan Tuggy

2

회사가 더 중대한 실수를 저질렀으며 이것은 단지 증상 일 뿐이라고 말하고 싶습니다. 생산 된 소프트웨어 의 도메인 을 제대로 결정하지 못하고 팀을 올바르게 관리하며 합리적인 목표를 정의하지 못했습니다.

팀에서 작성하는 소프트웨어가 사람의 생명에 의존하는 중요한 요소 인 경우 정적 분석 도구가 중요하고 유용합니다. 돈으로 측정 된 버그의 비용 (비싸지 않은 정도는 무시)이 높기 때문에 작업에 필요한 특수 도구가 있습니다. 언어 기능을 안전하게 사용하기위한 C 및 C ++에 대한 지침이 있습니다 (피해야 할 사항 및 피해야 할 거리를 읽으십시오).
그러나 그러한 상황에서 직원들이 일요일에 일하게하는 것은 매우 나쁜 생각입니다. 게다가 여러분이 제공 한 상황에서 나는 부주의 한 일이 드물지 않다고 추정합니다. 이 경우 문제는 매우경영진은 "더 나은"도구를 사용하여이를 해결하려고합니다. 불행히도, 그것은 일이 작동하지 않습니다. 내가 올바른 것에 가까워지면 다른 직업을 찾기 시작할 것을 제안한다. 미션 크리티컬 소프트웨어가 잘못되었다는 것은 소송 전망은 말할 것도없고 당신을 괴롭 히고 전문적인 명성을 망치는 것입니다.

반면에, 팀이 훨씬 덜 중요한 내용을 작성하는 경우, 오 탐지율이 높은 '정적 분석'도구를 사용하면 속도가 느려질 수 있습니다. 이 경우 근본적인 이유를 고치려고하지 않고 단순히 경고에 대해 속임수를 써서 효과의 로컬 최대 값을 찾는 것입니다. 따라서 이러한 도구를 사용하면 실제로 소스 코드의 품질이 저하 될 수 있으므로 일반적으로 피해야합니다.

경우 당신이 어떤 C 또는 C ++ 코드를 작성하는 소프트웨어 팀을 관리하는 데 필요한, 내가 주 프로젝트의 목표는 무엇인지 결정 먼저 말할 것입니다. 버그가없는 코드를 작성하는 것이 가장 중요하다면 (예 : iOS 및 Android 용 새로운 최고 소셜 앱 이 적합 하지 않은 경우) 정적 분석을 사용하고 공식 사양 및 공식 검증에 이르기까지 가능합니다. 그러나 이런 경우에는 좋은 프로그래머를 선택하고 적절한 작업량과 적절한 40 시간의 정상적인 환경에서 작업하는 것이 훨씬 더 중요합니다.

사람들은 노예처럼 대우 받으면 책임감있게 일할 수 없으며 (나의 휴일을 차지하는 누군가가 정확히 이것입니다) 좋은 프로그래머는 더 잘 알지 않는 한 정기적으로이를 거부 할 것입니다. 그들이하다).

요점 : 목표를 파악한 다음 사용하는 도구와 프로세스를 결정하고, 사용 가능한 도구가 프로세스를 (나쁜 목표) 강제로 강요하려는 프로세스로 정의하게하지 마십시오.


1

k.steff의 답변에 명시된 바와 같이 'C'에 대한 정적 분석 도구는 중요한 상황에서 소프트웨어를 구축하는 경우 유용하며 (비행기 소프트웨어) 재현 불가능한 버그가 발생할 때 개발 후 수개월이 지나지 않은 날부터 사용해야합니다. ).

개발 프로세스 후반에 이러한 종류의 도구를 사용하는 것은 일반적으로 프로세스 초기에 잘못된 설계 선택의 신호입니다.

중요하지 않은 소프트웨어에서 이러한 종류의 도구는 다음과 같은 경우에 유용합니다
. 파워 포인트 리포팅에서 쉽게 수행 할 수있는 작업을 제공합니다).
- '독성'개발자를 바쁘게 유지하십시오. 도구를 구성하고 도구 결과를 분석하여 불쾌한 버그를 해결할 시간을 가지십시오.
코딩 규칙을 강제합니다. 이 경우 첫날부터 사용해야합니다. 그러나 좋은 코드 검토 도구가 더 나은 선택 일 수 있습니다.

따라서 제 생각에는 이러한 종류의 비싸고 시간이 많이 걸리는 도구를 피하거나 '독성이있는'사람들을 바쁘게 유지하는 데 사용해야합니다.


1

나는 적어도 종이에서 Joel Test에서 11 점을받는 회사에서 일하고 있습니다.

Joel 테스트에 의한 검증은 모범 사례의 척도가 아닙니다. Joel 테스트에 의한 무효화는 나쁜 / 실종 관행의 척도입니다. 즉, 필요에 따라 볼 수 있지만 충분하지는 않습니다.

자, 대부분의 동료들은 일요일 오후 6시에 집으로 돌아갈 수 있다면 행복합니다.

관리 문제가있는 것 같습니다. 체계적인 초과 근무는 일을 끝내기위한 해결책이 아닙니다. 어떤 것이 든, 그것은 일을하고 기술 부채를 축적하는 것처럼 보이게 만드는 솔루션 입니다.

이제이 회사를 구할 수 있다고 생각하지 않습니다. 그러나 "프로"도구를 사용하는 것이 더 좋고, 바람직하게 작동하는 방법이 있는지, 또는 내가 미래에 결정을 내리는 경우에 대비하여 완전히 사용하지 않아야 하는지를 알고 싶습니다.

정적 코드 분석을 제정신 방식으로 사용하는 방법이 있습니다.

그들은 일반적으로 많은 가치를 제공 할 수 있습니다. (컴파일러 경고와 같이) 정적 분석 도구는 버그보고가 아니라 확실하지 않은 문제에 대한 힌트를 제공 할 수 있습니다.

의사 결정자들이 정적 분석 플래그를 응용 프로그램 결함과 혼동하는 것처럼 들립니다.

암시 적 캐스트도 스타일북에 블랙리스트에 올립니다.

이는 정적 분석 문제가 아니라 관리 역량 문제처럼 들립니다.

결과는 다음과 같습니다.

사람들은 프로세스에서 실제로 문제가되는 유형 불일치를 숨기는 모든 rvalue 및 모든 인수에 유형 캐스트를 추가합니다.

사람들은 하나의 버그로 소개하거나 다른 문제가있는 언어 기능을 사용합니다 (크기 대신에 strlen, strcpy 대신에 strncpy 등).

경고는 소리가 나지 않습니다.

버그 리포트가 시작됩니다.

이 모든 것은 코드의 문제를 해결하는 방법이 아니라주기적인 보고서를보기 좋게 만드는 방법입니다 (관리 역량 문제가있는 것 같습니다).

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