Delphi 함수에서 어떤 예외가 발생할 수 있는지 어떻게 알 수 있나요?

StackOverflow https://stackoverflow.com/questions/72562

  •  09-06-2019
  •  | 
  •  

문제

Delphi에서 프로시저/함수가 발생할 수 있는 예외(프로시저/함수 포함)를 알아낼 수 있는 좋은 방법이 있습니까?

Java에서는 항상 어떤 예외가 발생할 수 있는지 선언해야 하지만 Delphi에서는 그렇지 않아 처리되지 않은 예외가 발생할 수 있습니다.

처리되지 않은 예외를 감지하는 코드 분석 도구가 있습니까?

도움이 되었습니까?

해결책

(편집하다:이제 질문이 언급된 것이 분명해졌습니다. 오직 디자인 타임 확인에 사용됩니다.)

새로운 답변:

이를 확인할 수 있는 도구가 있는지 여부는 말씀드릴 수 없습니다.파스칼 분석기는 그렇지 않습니다.

~할 수 있다 그러나 대부분의 Delphi 애플리케이션에서는 이를 확인하는 도구가 있더라도 결과를 얻을 수 없습니다.

왜? TApplication.Run()의 기본 메시지 루프는 모든 예외 유형을 포착하는 예외 처리 블록에서 모든 HandleMessage() 호출을 래핑하기 때문입니다.따라서 대부분의 애플리케이션에서 약 99.999%의 코드를 처리하는 암시적/기본 예외를 갖게 됩니다.그리고 대부분의 애플리케이션에서 이 예외 처리는 사용자 코드의 약 100%에 해당합니다. 예외 처리에 포함되지 않은 코드의 0.001%는 자동으로 생성된 코드입니다.

이를 확인할 수 있는 도구가 있는 경우 예외 처리가 포함되지 않도록 Application.run()을 다시 작성해야 합니다.

(이전 답변:다른 예외 처리기에서 처리하지 않는 모든 예외를 catch하도록 Application.OnException 이벤트 처리기를 할당할 수 있습니다.이는 런타임이므로 정확히 원하는 것이 아닐 수도 있지만(디자인 타임에 이를 식별하려는 것처럼 들리지만) 다른 곳에서 처리되지 않은 예외를 트랩할 수 있습니다.JCLDebug와 같은 도구와 함께 제다이 코드 라이브러리, 스택 추적을 기록하여 예외가 발생한 위치와 이유를 알아낼 수 있으며, 이를 통해 추가 조사를 허용하고 유죄 코드에 대한 특정 예외 처리 또는 예방을 추가할 수 있습니다.)

다른 팁

내 생각엔 델파이를 자바처럼 동작하게 만들려는 것 같은데, 이는 좋은 접근 방식이 아닙니다.처리되지 않은 예외에 대해 너무 걱정하지 않는 것이 좋습니다.최악의 경우 일반 VCL 예외 핸들러까지 버블링되어 Windows 메시지 대화 상자가 표시됩니다.일반 애플리케이션에서는 애플리케이션을 중지하지 않습니다.

잘 작성된 코드는 발생할 수 있는 다양한 예외를 문서화하여 의미 있는 방식으로 처리할 수 있습니다.예외가 발생한 이유를 모르는 경우 실제로 무엇을 해야 할지 알 수 있는 방법이 없기 때문에 범용 핸들러는 권장되지 않습니다.madExcept를 적극 추천할 수도 있습니다.

"raise" 키워드에 대한 검색을 제외하고 Delphi에는 일반 독자에게 메서드에서 예상되는 예외를 알려주는 언어 구성이 없습니다.

런타임 시 모든 메서드에 포괄적인 예외 처리기를 추가할 수 있지만 실행 속도가 느려지므로 권장되지 않습니다.(그리고 그렇게 하는 것도 번거롭습니다).

메서드에 예외 처리 블록을 추가하면 (예외가 트리거되지 않은 경우에도) 몇 가지 어셈블리 명령이 추가되며, 이로 인해 메서드가 매우 자주 호출될 때 측정 가능한 속도 저하가 발생합니다.

다음과 같이 런타임 예외를 분석하는 데 도움이 되는 몇 가지 라이브러리가 있습니다. 미친 제외, Jcl디버그, 그리고 유레카로그.이러한 도구는 예외에 대한 모든 종류의 세부 정보를 기록할 수 있으므로 그 중 하나를 사용하는 것이 좋습니다!

짧은 대답은 당신이 말하는 것을 수행하는 도구가 없으며 심지어 들어올리다 키워드로는 거기까지 갈 수 없습니다. EAccess 위반 또는 EOutOfMemory 이는 어디에서나 발생할 수 있는 여러 예외 중 두 가지에 불과합니다.

Delphi의 한 가지 근본적인 점은 예외가 계층적이라는 것입니다.정의된 모든 언어 예외는 다음에서 유래합니다. 예외, 실제로 어떤 금액이라도 인상할 수 있다는 점은 주목할 가치가 있습니다. TObject 자손.

당신이 원한다면 잡다 특정 프로시저에서 발생하는 모든 예외는 시도 / 제외 차단하지만 앞서 언급했듯이 이것은 권장되지 않습니다.

// Other code . . . 
try
  SomeProcedure()
except  // BAD IDEA!
  ShowMessage('I caught them all!');
end;

그것은 모든 것을 잡을 것입니다. 심지어 제기된 경우도 마찬가지입니다. TObject.나는 이것이 최선의 행동 방침이 아니라고 주장하고 싶습니다.일반적으로 다음을 사용하고 싶습니다. 시도하다 / 마침내 차단한 다음 전역 예외 처리기(또는 최종 시도 / 제외 블록) 실제로 예외를 처리합니다.

나는 두 번째로 할 것이다(아니면 세 번째로 할 것인가) MadExcept.나는 여러 상용 응용 프로그램에서 아무 문제 없이 성공적으로 사용해 왔습니다.MadExcept의 좋은 점은 무엇이 잘못되었는지에 대해 일반적으로 올바른 방향을 알려주는 전체 스택 추적이 포함된 보고서를 생성하고 스크린샷도 포함할 수 있으며 자동으로 이메일로 전송된다는 것입니다. 간단한 마우스 클릭만으로 클라이언트 컴퓨터에서.

그러나 모든 예외에 대해 이것을 사용하고 싶지는 않으며 단지 놓친 예외를 잡기 위해서입니다.예를 들어, 데이터베이스를 열었는데 로그인이 실패한 경우 사용자에게 애플리케이션 발생 메시지에서 MadExcept 기본 오류를 제공하는 것보다 직접 이를 잡아서 처리하는 것이 더 나을 것입니다.

특정 수준에서 명시적으로 또는 일반적으로 처리되지 않은 모든 예외는 호출 스택에서 위쪽으로 흘러갑니다.Delphi RTL(런타임 라이브러리)은 다양한 예외 클래스 세트(수학적 오류, 액세스 오류, 클래스별 오류 등)를 생성합니다.블록을 제외한 다른 try에서 구체적으로 또는 일반적으로 처리하도록 선택할 수 있습니다.

예외와 함께 특정 기능 컨텍스트를 전파해야 하는 경우가 아니면 실제로 새 예외 클래스를 선언할 필요가 없습니다.

이전 댓글 작성자가 쓴 것처럼 MadExcept 또는 EurekaLog와 같은 모든 예외 처리기의 어머니를 추가하여 잡히지 않는 예외를 잡을 수도 있습니다.

편집하다:이는 처리되지 않은 예외에 대한 포괄적인 보험입니다.

try
  ThisFunctionMayFail;
except
  // but it sure won't crash the application
  on e:exception
  do begin
    // something sensible to handle the error 
    // or perhaps log and/or display the the generic e.description message
  end
end;

런타임을 위해 시도하십시오 유레칼로그.디자인 타임을 위한 도구가 존재하는지 모르겠습니다.소스가 없는 제3자 코드가 있는 경우에도 더 많은 어려움을 겪게 됩니다.Delphi에서는 예외를 잡을 필요가 없으므로 Java처럼 예외를 선언할 필요가 없습니다.

제가 말하고 싶은 것은 델파이에서는 예외 처리를 요구하지 않는다는 것입니다.프로그램이 종료됩니다.EurekaLog는 처리된 예외와 처리되지 않은 예외를 기록하는 수단을 제공하고 예외가 발생한 코드 줄과 당시 호출 스택을 포함하여 예외가 발생했을 때 프로그램 상태에 대한 풍부한 정보를 제공합니다.

Jim McKeeth가 지적했듯이, 확실한 답을 얻을 수는 없지만, 제가 보기에는 답을 얻을 수 있을 것 같습니다. 부분적으로 정적 분석을 통해 질문에 답하십시오.특정 함수/프로시저가 주어지면 호출 그래프를 구성합니다.호출 그래프의 각 함수에서 raise 문을 확인하세요.예를 들어 TIdTcpClient.ReadString이 EIdNotConnected(다른 것 중에서)를 발생시킬 수 있음을 알려줍니다.

영리한 분석기는 일부 코드가 / 연산자를 사용하고 EDivByZero를 가능성으로 포함하거나 일부 프로시저가 배열에 액세스하여 ERangeError를 포함한다는 점을 지적할 수도 있습니다.

그 대답은 단순히 "인상"을 찾는 것보다 조금 더 엄격합니다.

유닛의 마무리 섹션에서도 예외가 발생할 수 있습니다.이것들은 그냥 지나갈 것 같아요...또한 다소 문제가 있습니다.

내 생각에 Delphi IDE에는 "스택 추적" 또는 "스택 트리"와 같은 기능이 내장되어 있는 것 같습니다.

이 질문은 Skybuck의 TRussianRoulette 게임을 생각나게 합니다...Google에서 코드와 답변이 도움이 될 수 있습니다.

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