"현재 방법의 코드가 최적화되어 있기 때문에 표현을 평가할 수 없습니다." 평균?

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

문제

나는 재귀가 많은 코드를 썼는데, 완료하는 데 시간이 많이 걸립니다. 내가 무슨 일이 일어나고 있는지보기 위해 달리기를 "일시 중지"할 때마다 나는 얻을 수있다.

현재 방법의 코드가 최적화되었으므로 표현식을 평가할 수 없습니다.

나는 그것이 무엇을 의미하는지 이해한다고 생각합니다. 그러나 저를 퍼즐로 한 것은 단계를 치면 코드가 더 이상 "최적화되지 않은"것이 아니며 내 변수를 볼 수 있다는 것입니다. 이런 일이 어떻게 발생합니까? 코드가 최적화 된 코드와 최적화되지 않은 코드 사이를 어떻게주고받을 수 있습니까?

도움이 되었습니까?

해결책

디버거는 funceval을 사용하여 변수를 "볼 수 있습니다". Funceval은 GarbageCollector Safe Point에서 관리 코드로 스레드를 중지해야합니다. IDE에서 실행되면 수동으로 "일시 정지"하면 모든 스레드가 가능한 빨리 멈추게됩니다. 당신의 매우 재귀적인 코드는 안전하지 않은 지점에서 멈추는 경향이 있습니다. 따라서 디버거는 표현식을 평가할 수 없습니다.

F10을 누르면 다음 Funceval Safe Point로 이동하여 기능 평가가 가능합니다.

자세한 정보를 검토하려면 funceval의 규칙.

다른 팁

Debug.break () 라인이 CallStack 위에있는 동안 표현식을 평가할 수는 없습니다. 그 라인이 최적화 되었기 때문입니다. F10을 눌러 다음 줄 (유효한 코드 라인)으로 이동하면 시계가 작동합니다.

디버그 모드 대신 릴리스 모드에서 앱을 디버깅하려고하거나 컴파일 설정에서 최적화가 켜져 있습니다.

코드가 최적화로 컴파일되면 기능에 더 이상 사용되지 않으면 특정 변수가 제거되므로 해당 메시지를받는 이유입니다. 최적화가 비활성화 된 디버그 모드에서는 해당 오류가 발생하지 않아야합니다.

이것은 나를 미치게했다. 관리 및 기본 코드로 첨부를 시도했습니다.

이것은 저에게 효과가 있었고 마침내 모든 표현을 평가할 수있었습니다.

  • 프로젝트 / 속성으로 이동하십시오
  • 빌드 탭을 선택하고 고급을 클릭하십시오 ...
  • 디버그 정보가 "전체"로 설정되어 있는지 확인하십시오 (PDB 전용이 아님)
  • 프로젝트 디버그 - voila!

아래는 저를 위해 일했습니다. 감사합니다 @vin.

VS 2015를 사용할 때이 문제가있었습니다. 솔루션 : Configuration (Debug)이 선택되었습니다. 나는 이것을 선택 해제하여 이것을 해결했습니다 Optimize Code 프로젝트 속성에 따른 속성.

project (오른쪽 클릭) => properties => build (탭) => 코드 최적화 해제

많은 매개 변수가있는 함수 호출을 찾고 디버깅이 반환 될 때까지 숫자를 줄이십시오.

그런 것이 없는지 확인하십시오

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]

당신의 AssemblyInfo

Microsoft의 친구의 친구가 다음을 보냈습니다.http://blogs.msdn.com/rmbyers/archive/2008/08/16/func_2d00_eval-pail-while-stopped-in-a-non_2d00_optimized-manged-method-that-pushes-more-than-256- Argument-bytes -.aspx

가장 큰 문제는 메소드 서명이 너무 커서 통화 스택이 최적화된다는 것입니다.

같은 문제가 있었지만 디버거에서 예외 트래핑을 끄면 해결할 수있었습니다. [Debug] [예외]를 클릭하고 예외를 "사용자 유도"로 설정하십시오.

일반적으로 나는 이것을 가지고 있지만 가끔 편리합니다. 완료되면 끄는 것을 기억해야합니다.

VS 2010을 사용할 때이 문제가있었습니다. 솔루션 구성 (디버그)이 선택되었습니다. 프로젝트 속성에서 최적화 코드 속성을 선택 취소하여이를 해결했습니다. project (오른쪽 클릭) => properties => build (탭) => 코드 최적화 해제

제 경우에는 솔루션에 2 개의 프로젝트가 있었고 스타트 업 프로젝트가 아닌 프로젝트를 운영하고있었습니다. 시작 프로젝트로 변경했을 때 디버깅이 다시 작동하기 시작했습니다.

그것이 누군가를 돕기를 바랍니다.

평가:

.NET에서 "Function Evaluation (Funceval)"은 Debuggee가 어딘가에 중단되는 동안 CLR이 임의의 호출을 주입하는 능력입니다. Funceval은 요청 된 메소드를 실행하기 위해 디버거의 선택된 스레드를 담당합니다. Funceval이 끝나면 디버그 이벤트를 시작합니다. 기술적으로 CLR은 디버거가 Funceval을 발행하는 방법을 정의했습니다.

CLR은 GC Safe Point (예 : 스레드가 GC를 차단하지 않는 경우) 및 Funceval Safe (Fesafe) 포인트 (즉, CLR이 실제로 Funceval을 위해 납치를 할 수있는 FENCEVAL SAFE) 포인트에있는 스레드에서만 FUNCEVAL을 시작할 수 있습니다. 따라서 CLR에 대한 가능한 시나리오, 스레드는 다음과 같습니다.

  1. 관리 코드 (및 GC Safe Point)에서 중지 : 이는 기본 코드로 funceval을 수행 할 수 없음을 의미합니다. 기본 코드는 CLR의 컨트롤을 벗어나므로 Funceval을 설정할 수 없습니다.

  2. 첫 번째 기회 또는 처리되지 않은 관리 예외 (및 GC Safe Point)에 중지 : 예외적으로 예외가 발생하여 예외가 발생한 이유를 결정하기 위해 가능한 한 많이 검사합니다. (예 : Debugger는 예외가 발생하는 메시지 속성을 평가하고 볼 수 있습니다.)

전반적으로, 관리되는 코드에서 중지하는 일반적인 방법에는 중단 점, 단계, 디버거. 브레이크 호출, 예외를 가로 채기 또는 스레드 시작에서 중지하는 것이 포함됩니다. 이것은 방법과 표현을 평가하는 데 도움이됩니다.

가능한 결의 : 평가에 따라 스레드가 Fesafe 및 GCSafe 포인트에 있지 않은 경우 CLR은 스레드를 납치하여 Funceval을 시작할 수 없습니다. 일반적으로 다음은 Funceval이 예상 할 때 시작하는지 확인하는 데 도움이됩니다.

1 단계:

"릴리스"빌드를 디버깅하려고하지 않도록하십시오. 릴리스는 완전히 최적화되어 토론의 오류로 이어집니다. 표준 도구 모음 또는 구성 관리자를 사용하면 디버그 및 릴리스를 전환 할 수 있습니다.

2 단계:

여전히 오류가 발생하면 디버그 옵션이 최적화를 위해 설정 될 수 있습니다. 프로젝트“Properties”에서“최적화 코드”속성을 확인하고 선택 취소하십시오.

프로젝트 선택 옵션을 마우스 오른쪽 버튼으로 클릭하여 "속성" "빌드"탭으로 이동 확인란을 선택 취소 "코드 최적화"

3 단계 :

여전히 오류가 발생하면 디버그 정보 모드가 잘못 될 수 있습니다. "고급 빌드 설정"에서 "전체"로 확인하고 설정하십시오.

프로젝트 선택 옵션“속성”옵션을 마우스 오른쪽 버튼으로 클릭하십시오.“빌드”탭으로 이동하십시오.“고급”버튼을 "Debug Info"로 "full"으로 클릭하십시오.

4 단계 :

여전히 문제에 직면해도 다음을 시도하십시오.

디버깅 중에 솔루션 파일의 "깨끗한"및 "재건"을 수행하십시오. 모듈 창 (vs 메뉴 -> 디버그 -> Windows-> 모듈)로로드 된 모듈 목록에서 어셈블리를 찾으십시오. 로드 된 어셈블리에 대해 나열된 경로를 점검하여 파일의 수정 된 타임 스탬프를 점검하여 조립품이 실제로 재건되었는지 확인하는지 확인하십시오.로드 된 모듈이 최적화되었는지 여부를 확인하십시오.

결론:

오류가 아니라 특정 설정을 기반으로하고 .NET 런타임 작동 방식을 기반으로 설계된 정보입니다.

제 경우에는 릴리스 모드에 있었고 모든 것이 작동하도록 변경했습니다.

비슷한 문제가 있었고 디버그 모드에서 솔루션을 빌드하고 실행 경로에서 PDB 파일을 교체 할 때 해결되었습니다.

나는 당신이보고있는 것이 최적화의 결과라고 생각합니다. 때로는 변수가 재사용 될 것입니다. 특히 스택에 생성되는 변수. 예를 들어, 두 개의 (로컬) 정수를 사용하는 메소드가 있다고 가정합니다. 첫 번째 정수는이 방법의 시작 부분에서 선언되며 루프의 카운터로만 사용됩니다. 두 번째 정수는 루프가 완료된 후 사용되며 나중에 파일에 기록 된 계산 결과를 저장합니다. 이 경우 Optimiser는 첫 번째 정수를 재사용하여 두 번째 정수에 필요한 코드를 저장하기로 결정할 수 있습니다. 두 번째 정수를 일찍 보려고 할 때 "표현을 평가할 수 없음"에 대한 메시지를받습니다. 정확한 상황을 설명 할 수는 없지만 Optimiser가 두 번째 정수의 값을 나중에 별도의 스택 항목으로 전송할 수 있으므로 디버거에서 값에 액세스 할 수 있습니다.

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