2009-09-23 3 views
3

지난 며칠 동안 제 3자가 개발 한 데이터베이스 구성 요소에 이상한 문제가있었습니다. 이러한 구성 요소는 몇 달 동안 변경되지 않았습니다. 지난 며칠 동안 변경된 코드는 자체 코드이며 다른 제 3자가 개발 한 GUI 구성 요소도 업데이트했습니다. 내가 찾은 디버깅 후System.Move가 때로 잘못된 결과를 낼 수있는 원인은 무엇입니까?

은 데이터베이스 구성 요소의 절차 중 하나에 System.Move에 대한 호출은 occationaly 잘못된 결과를 준다!

하면 데이터베이스 구성 요소에서 아래의 코드를 살펴보고 내 의견을 읽어 보시기 바랍니다. 이 모순 된 행동은 어떻게 일어날 수 있습니까? 누구나이 일관성없는 행동의 원인을 찾기 위해 절차를 수행하는 방법에 대한 아이디어를 줄 수 있습니까? NB! 나는이 코드에 문제가 있다고 생각하지 않는다. 문제의 "증상"을 설명하기 위해서만 보여진다. 제 생각에 우리 코드 나 업데이트 된 gui-component-code로 인해 메모리 손상이나 무언가가 발생했습니다.

편집 : 아래에 링크 된 블로그 게시물을 살펴보십시오. 내 문제와 관련이있는 것 같습니다. http://blog.excastle.com/2007/08/28/delphi-bug-of-the-day-fpu-stack-leak/

편집 : 나는 그것을 읽고 적어도 그것은 System.Move 잘못된 결과를 줄 수있는 것을 확인 내 "솔루션"earlyer을 게시하지 죄송하지만 여기 온다 : 내 문제가 있었다 델파이 2007을 사용하는 경우 System.Move를 대체하는 FastMove를 사용하여 해결되었습니다. Delphi 2010으로 업그레이드 한 후에도 아직 문제가 발생하지 않았으므로 더 이상 FastMove를 사용하지 않습니다.

Procedure InternalDescribe; 
var 
    cbufl: sb4; //sb4=LongInt 
    cbuf: array[0..30] of char; 
    cbufp: PChar; 
    //.... 
begin 
    //..Some code 
    repeat 
    //...Some code to initialize cbufp and cbufl 

    //On the 15. iteration the values immediately Before Move are always these: 
    //cbufp = 'STDPRODUCTSTOREDELEMENTSCOUNT' 
    //cbuf = ('S', 'T', 'A', 'T', 'U', 'S', #0, 'E', 'V', 'A', 'R', 'R', 'E', 'C', 'I', 'D', #0, 'D', 'U', 'C', 'T', 'I', 'D', #0, #0, #0, #0, #0, #0, #0, #0) 
    //cbufl = 29 

    Move(cbufp^, cbuf, cbufl); 

    //Values immediately After Move should then be: 
    //cbuf = ('S', 'T', 'D', 'P', 'R', 'O', 'D', 'U', 'C', 'T', 'S', 'T', 'O', 'R', 'E', 'D', 'E', 'L', 'E', 'M', 'E', 'N', 'T', 'S', 'C', 'O', 'U', 'N', 'T', #0, #0) 

    //But sometimes this Move results in this value(1 in 5..15 times): 
    //cbuf = ('S', 'T', 'D', 'P', 'R', 'O', 'D', 'U', 'C', 'T', 'S', 'T', 'O', 'R', 'E', 'D', #0, #0, #0, #0, #0, 'N', 'T', 'S', 'C', 'O', 'U', 'N', 'T', #0, #0) } 

    until SomeCondition; 
    //...Some more code 
end; 
+1

사용중인 Delphi 버전과 최근에 Delphi 버전을 업그레이드했는지 여부를 포함시켜야합니다. 사람들이 귀하의 질문에 쉽게 답할 수있게 해줍니다. –

+0

델파이 2007 for Win32입니다. 또한 FastMM4를 사용합니다. (내 질문이 아니지만 나는 그를 안다.) –

+0

나는 나의 계정을 고쳤으며 나의 모든 대답을 나의 "대답"에서 옮기고 그 대답에 대한 진정한 논평을했다. –

답변

0

현재 코드를 수정하지 않고 이전 GUI 구성 요소 코드로 되돌릴 수 있습니까? 이렇게하면 코드 또는 GUI 구성 요소인지 확인할 수 있습니다.

또 다른 문제는 여러 스레드를 사용하고 있다는 것을 있건 없건간에이다.

편집 : 테스트 목적으로 GUI 구성 요소를 되돌리고 싶습니다. 최신 버전으로 업데이트해야합니다. 하지만 또 한 번 시험해 볼게. 이동 작업 전에 버퍼를 0으로 만들려고 했습니까? 이 작업을 수행하려면 FillChar 절차를 참조하십시오. 이게 도움이 되나요?

+0

예 되돌릴 수 있습니다. 나는 이것을 시도 할 계획 이었지만 결코 그것에 도달하지 못했습니다. 실제로 문제가 gui 구성 요소에서 오는 것이 확실합니다. 왜냐하면 "gui"를 코드에서 분리하면 아직 문제가 발생하지 않았기 때문입니다. 그러나 우리는 이유만으로 구성 요소를 업그레이드했기 때문에 되돌릴 수는 없으며 만족하고 싶습니다. 그러나 나는 단지 나의 의심을 확인/반증하기 위해 그것을 시도 할 것이다. 너무 심하게 나는 며칠 동안 일하지 않을 것이다. –

6

이동 잘못된 결과를 제공하지 않습니다, 또는 적어도 나는 한있는 모든 상황을 본 적이 없습니다. 버퍼에서 예기치 않은 것을 얻었을 가능성이 큽니다. 이 루틴의 Windows.OutputDebugString에 대한 호출을 추가하여 이전 및 이후에 복사중인 내용을 확인하십시오.

+0

System.Move는 대개 잘못된 결과를주지는 않지만 지금까지 볼 수있는 한 멀리합니다. 코드에서 내 의견을 보면 System.Move에 올바른 입력이 실제로 잘못된 결과를주는 것을 실제로 목격했습니다. –

2

주의 - Char = 1 바이트라고 가정합니다. D2009 이전에는 괜찮 았지만 D2009 및 D2010에서는 char이 2 바이트입니다. 이동은 항상 바이트로 작동합니다. D2009 또는 D2010으로 업그레이드 한 후 이러한 문제가 발생할 수 있습니까?

+1

우리는 Delphi 2007을 사용하고 있으므로 이것이 내 문제의 원인이 아닙니다. –

1

가끔 실패 할 수 있습니다. 나는 그것을 추적하는 데 며칠을 보냈다. 믿을 수가 없어. 우리의 경우 .NET 2.0, Delphi 2007로 작성된 일부 COM 구성 요소를 호출하는 IIS 6 또는 IIS 7에서 실행되는 웹 사이트가 있으며 보통의로드에서는 갑자기 28 바이트 중 16-19 바이트를 이동하지 못합니다. 대부분의 경우 작동합니다. 9..31 바이트 범위의 크기로 이동하면 문제를 일으킬 가능성이 거의 없습니다.

우리는 CompareMem() 각 시스템 후 확인을 가하고 결국.Move()는 ComparewMem이 가끔씩 실패했다는 것을 알았습니다. 그리고 이것은 스택에 두 개의 버퍼/배열/구조체 사이를 이동했습니다! 소년은 놀랐다!

복제 연령이 오래되었습니다. 본질적으로 D2006 이후의 System.Move는 FPU 스택에 남아있는 물건으로 인해 신뢰할 수 없습니다. FPU 스택이 명확하다면 모두 괜찮을까요?

위에서 언급 한 블로그 게시물 항목이 정확합니다. 아무리 고침이라도 system.Move()에 영향을 미치지 않으므로 Delphi 2006 또는 이후 버전에서 작성된 DLL/COM이 있으면 어떤 단계에서 문제가 발생합니다.

D2010을 체크했는데 System.Move의 코드가 변경되지 않았습니다. 여기서는 System.Move를 Delphi 7 버전으로 되돌릴 것입니다. make 파일을 사용하여 모든 시스템 유닛을 다시 컴파일하면됩니다.

0

귀하의 정보를 위해서 (다른 고객들도 동일한 문제가있을 경우를 대비하여) : 우리는 고객을 위해 소프트웨어를 업그레이드했으며 응용 프로그램이 시작되면 완전한 터치 스크린이 잠겼습니다! Windows가 완전히 정지되었습니다! PC를 다시 시작해야했습니다 (전원을 끕니다). 완전한 동결의 원인을 알아내는 데 시간이 걸렸습니다.

다행히도 FastMove.LargeSSEMove에 AV의 스택 트레이스가 하나만있었습니다. fastmove에서 SSE 사용을 비활성화했으며 문제가 해결되었습니다.

그런데 터치 스크린에는 S3 칩셋이있는 VIA Nehemiah cpu가 있습니다.

관련 문제