문제

우리는 이식 가능한 코드(win+macOs)를 생성하고 있으며 자주 충돌하므로 코드를 더욱 견고하게 만드는 방법을 찾고 있습니다.(일반적으로 오버플로 또는 잘못된 초기화) :-(

Google 크롬은 모든 탭에 대해 프로세스를 사용하므로 문제가 발생하더라도 프로그램이 완전히 충돌하지 않고 해당 탭만 충돌한다는 내용을 읽었습니다.꽤 깔끔하다고 생각해서 한번 시도해 볼 수도 있겠네요!

그래서 누군가가 좀 더 견고한 C++ 코드를 작성하는 데 도움이 될 수 있는 몇 가지 팁, 도움말, 읽기 목록, 의견 또는 무언가를 가지고 있는지 궁금합니다(이식성은 항상 더 좋습니다).

같은 주제에서 (부스트와 같은) 프로세스를 위한 이식 가능한 라이브러리가 있는지도 궁금합니다.

정말 감사합니다.

도움이 되었습니까?

해결책

저는 수많은 멀티 플랫폼 C++ 앱(가장 큰 코드 라인은 150만 라인이고 AIX, HP-UX PA-RISC, HP-UX Itanium, Solaris, Linux, Windows, OS X 등 7개 플랫폼에서 실행됨)에서 개발했습니다. .실제로 게시물에는 완전히 다른 두 가지 문제가 있습니다.

  1. 불안정.코드가 안정적이지 않습니다.문제를 해결하세요.

    • 단위 테스트를 사용하여 논리 문제로 인해 문제가 발생하기 전에 찾아보세요.
    • 명확하지 않은 경우 디버거를 사용하여 충돌을 일으키는 원인을 찾으십시오.
    • 부스트 및 유사한 라이브러리를 사용하십시오.특히 포인터 유형은 메모리 누수를 방지하는 데 도움이 됩니다.
  2. 크로스 플랫폼 코딩.

    • 가능하면 이를 위해 설계된 라이브러리를 다시 사용하십시오.특히 모든 GUI 비트의 경우.
    • 표준을 사용합니다(예:조금 더 많은 작업이 필요하더라도 ANSI 대 gcc/MSVC, POSIX 스레드 대 Unix 특정 스레드 모델 등)을 최대한 많이 사용하세요.플랫폼별 코드를 최소화하면 전체 작업량이 줄어들고 학습할 API도 줄어듭니다.
    • 격리하고, 격리하고, 격리하세요.다양한 플랫폼에 대한 인라인 #ifdef를 최대한 피하세요.대신 플랫폼별 코드를 자체 헤더/소스/클래스에 고정하고 빌드 시스템과 #include를 사용하여 올바른 코드를 얻으세요.이는 코드를 깔끔하고 읽기 쉽게 유지하는 데 도움이 됩니다.
    • 가능하다면 "long", "int", "short" 등 대신 C99 정수 유형을 사용하십시오. 그렇지 않으면 32비트 플랫폼에서 64비트 플랫폼으로 이동하고 long이 갑자기 변경될 때 문제가 될 것입니다. 4바이트에서 8바이트로.그리고 그것이 네트워크/디스크/등에 기록되면 플랫폼 간에 비호환성이 발생하게 됩니다.

개인적으로 저는 먼저 (더 이상 기능을 추가하지 않고) 코드를 안정화한 다음 크로스 플랫폼 문제를 처리하겠지만 그건 여러분에게 달려 있습니다.Visual Studio에는 뛰어난 디버거가 있습니다(위에서 언급한 코드 베이스는 바로 이러한 이유로 Windows로 이식되었습니다).

다른 팁

Chrome 답변은 코드 품질이 아니라 오류 완화에 관한 것입니다.Chrome이 하는 일을 하는 것은 패배를 인정하는 것입니다.

  1. 프로그래머가 자신의 작업을 테스트하는 것 이상의 더 나은 QA입니다.
  2. 단위 테스트
  3. 회귀 테스트
  4. 다른 회사에서 사용하는 모범 사례를 읽으십시오.

직설적으로 말하자면, 오버플로와 잘못된 초기화로 인해 소프트웨어가 자주 충돌하는 경우 쉽게 해결되지 않는 매우 기본적인 프로그래밍 품질 문제가 있는 것입니다.그것은 해시하고 의미하는 것처럼 들리지만 내 의도는 아닙니다.내 요점은 잘못된 코드 문제가 주요 관심사가 되어야 한다는 것입니다(확실히 그렇습니다).프로그램 결함을 잡기 위해 Chrome을 사용하거나 예외 처리를 자유롭게 사용하는 등의 작업은 실제 문제에 집중하는 데 방해가 될 뿐입니다.

대상 프로젝트가 무엇인지 언급하지 않았습니다.탭별로 프로세스가 있다고 해서 반드시 더 "견고한" 코드를 의미하는 것은 아닙니다.이식성에 관계없이 테스트를 통해 견고한 코드를 작성하는 것을 목표로 해야 합니다. 좋은 C++ 코드 작성에 대해 읽어보세요 :)

이식성 섹션의 경우 첫날부터 두 플랫폼 모두에서 테스트하고 플랫폼별 문제가 해결될 때까지 새 코드가 작성되지 않도록 하십시오.

당신은 정말로 Chrome이 하고 있는 일을 하고 싶지 않습니다. 당신이 원하는 것에 비해 너무 과도한 프로세스 관리자가 필요할 것입니다.

Boost 또는 C++에 대한 참조 계산 또는 가비지 수집을 제공하는 다른 도구의 스마트 포인터 사용을 조사해야 합니다.

또는 자주 충돌하는 경우 C++ 바인딩이 있는 스크립팅 언어로 애플리케이션의 성능에 중요하지 않은 부분을 작성하는 것을 고려할 수 있습니다.

스캇 마이어스' 효과적인 C++ 그리고 더욱 효과적인 C++ 매우 좋고, 읽기 재미있습니다.

스티브 맥코넬의 코드 완성 Jeff Atwood를 포함하여 많은 사람들이 좋아하는 작품입니다.

Boost 라이브러리는 아마도 탁월한 선택일 것입니다.내가 일하는 한 프로젝트에서는 이를 사용합니다.저는 WIN32 스레딩만 사용해 왔습니다.

나는 Torlack에 동의합니다.

잘못된 초기화 또는 오버플로는 코드 품질이 좋지 않다는 신호입니다.

Google은 때때로 (잘못된 플러그인 등으로 인해) 페이지에서 실행된 코드를 제어할 수 있는 방법이 없었기 때문에 그렇게 했습니다.따라서 품질이 낮은 플러그인을 사용하는 경우에는 Google 솔루션이 도움이 될 수 있습니다.

그러나 종종 충돌이 발생하는 플러그인이 없는 프로그램은 잘못 작성되었거나 매우 복잡하거나 매우 오래되었습니다(그리고 유지 관리 시간이 많이 누락됨).개발을 중단하고 모든 충돌을 조사해야 합니다.Windows에서는 PDB(프로그램 데이터베이스)로 모듈을 컴파일하고 충돌이 발생할 때마다 디버거를 연결합니다.

내부 테스트도 추가해야 합니다.다음 패턴을 피하세요.

doSomethingBad(T * t)
{
   if(t == NULL) return ;

   // do the processing.
}

오류가 있기 때문에 이것은 매우 나쁜 디자인이며, 그냥 피하면 됩니다. 이 시간.하지만 이 가드가 없으면 다음 함수는 충돌할 것입니다.오류에 더 가까워지려면 더 빨리 충돌하는 것이 좋습니다.

대신 Windows에서는 (MacOS에도 비슷한 API가 있어야 합니다)

doSomethingBad(T * t)
{
   if(t == NULL) ::DebugBreak() ; // it will call the debugger

   // do the processing.
}

(이 코드를 직접 사용하지 마세요...클라이언트에게 전달하는 것을 피하기 위해 정의에 넣으십시오 ...) 당신은 자신에게 맞는 오류 API를 선택할 수 있지만 (예외, 디버그 브레이크, 어제 등) 코드가 무언가 잘못 알고있는 순간을 멈추는 데 사용하십시오.

가능하면 C API를 사용하지 마세요.C++ 관용구(RAII 등)와 라이브러리를 사용하세요.

등..

추신.:예외를 사용하는 경우(좋은 선택임) 예외를 catch 안에 숨기지 마세요.오류가 있기 때문에 문제가 더 악화될 뿐입니다. 그러나 프로그램은 계속하려고 시도하고 이후에 때때로 충돌이 발생하고 그 동안 접촉한 모든 것이 손상될 수 있습니다.

이러한 종류의 오류를 포착하고 무시하기 위해 언제든지 프로그램에 예외 처리를 추가할 수 있습니다(세부 사항은 플랫폼에 따라 다름).하지만 그것은 양날의 검입니다.대신 프로그램이 예외를 포착하고 분석을 위해 덤프 파일을 생성하도록 하는 것을 고려하십시오.

프로그램이 예상치 못한 방식으로 작동했다면 내부 상태에 대해 무엇을 알고 있습니까?충돌이 발생한 루틴/스레드가 일부 주요 데이터 구조를 손상시켰을 수 있습니까?어쩌면 오류를 포착하고 계속하려고 하면 사용자가 작업 중인 모든 것을 저장하고 손상을 디스크에 커밋하게 될까요?

보다 안정적인 코드를 작성하는 것 외에도 귀하의 질문에 답하는 한 가지 아이디어가 있습니다.

프로세스 또는 스레드를 사용하는지 여부.작고 간단한 감시 프로그램을 작성할 수 있습니다.그런 다음 다른 프로그램이 해당 감시 장치에 등록됩니다.프로세스가 종료되거나 스레드가 종료되면 워치독에 의해 다시 시작될 수 있습니다.물론 동일한 버그가 있는 스레드를 계속 다시 시작하지 않는지 확인하기 위해 몇 가지 테스트를 수행하고 싶을 것입니다.즉:5번 다시 시작하고 5번 이후에는 전체 프로그램을 종료하고 파일/syslog에 기록합니다.

디버그 기호를 사용하여 앱을 빌드한 다음 예외 처리기를 추가하거나 Dr Watson을 구성하여 크래시 덤프를 생성합니다(drwtsn32.exe /i를 실행하여 디버거로 설치하고 구성 대화 상자를 표시하는 /i 없이).앱이 충돌하면 Windbg 또는 Visual Studio에서 호출 스택과 변수를 확인하여 어디에서 문제가 발생했는지 검사할 수 있습니다.

자세한 내용은 기호 서버용 Google을 참조하세요.

분명히 예외 처리를 사용하여 더욱 강력하게 만들고 스마트 포인터를 사용할 수 있지만 버그를 수정하는 것이 가장 좋습니다.

나는 당신이 리눅스 버전을 컴파일하고 아래에서 실행하는 것이 좋습니다 발그린드.

Valgrind는 메모리 누수, 초기화되지 않은 메모리 읽기 및 기타 여러 코드 문제를 추적합니다.나는 그것을 강력히 추천합니다.

15년 넘게 Windows를 개발한 후 최근에 첫 번째 크로스 플랫폼 C++ 앱(Windows/Linux)을 작성했습니다.방법은 다음과 같습니다.

  • STL
  • 후원.특히 파일 시스템과 스레드 라이브러리.
  • 브라우저 기반 UI.앱은 XHTML/CSS/JavaScript(Ajax 스타일)로 구성된 UI를 사용하여 HTTP를 '수행'합니다.이러한 리소스는 서버 코드에 포함되어 필요할 때 브라우저에 제공됩니다.
  • 풍부한 단위 테스트.TDD는 아니지만 가깝습니다.이것은 실제로 제가 개발하는 방식을 바꾸었습니다.

저는 Linux 빌드에 NetBeans C++를 사용했고 즉시 전체 Linux 포트를 갖게 되었습니다.

종료할 수 있는 유일한 방법은 프로그램이 충돌하는 것이고 언제든지 충돌할 수 있다는 생각을 가지고 구축하십시오.그런 식으로 구축하면 충돌이 발생해도 데이터가 전혀 손실되지 않습니다.1~2년 전에 이에 관한 기사를 읽었습니다.아쉽게도 링크가 없네요.

이를 일종의 크래시 덤프와 결합하여 이메일로 보내면 문제를 해결할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top