Спорадическое нарушение прав доступа после переноса с D2006 на XE5 не происходит в режиме совместимости с XP

У нас есть большое приложение, которое отлично работает в Delphi 2006. Мы перенесли его на XE5 и сталкиваемся с частыми спорадическими нарушениями прав доступа. Мы используем формы VCL и ряд компонентов DevExpress и других сторонних производителей. Мы работаем в Windows 7 Professional с Delphi XE Enterprise, версия 19.0.14356.6604.

Мы искали в Интернете, здесь и в других местах, сообщения об аудио/видео после переноса на XE5, но не нашли ничего, что имело бы отношение к нашей проблеме.

Вот что мы знаем об аудио/видео:

  • Обычно они встречаются по одному и тому же адресу: 0x50059f27. Иногда они происходят по адресу 0x5005eb86, обычно после того, как аудио/видео уже было запущено по другому адресу.
  • Они происходят из разных мест и действий в приложении.
  • Они не воспроизводятся на 100%. Иногда перестроение проекта устраняет один триггер, но затем его запускает что-то другое. Кажется, они остаются довольно последовательно воспроизводимыми в сборках.
  • Как правило, они связаны либо с открытием диалогового окна, либо с активацией запроса, который возвращает значительное количество записей (более 1000).
  • Этого не происходит с версией D2006 (которую мы запускаем на компьютерах с XP или на виртуальной машине XP). - Их не происходит, когда мы запускаем приложение XE5 в режиме совместимости с XP-SP3.
  • Если мы прервемся после типичного A/V, указатель будет находиться в System.pas в строке 562, в разделе {$IFDEF CPUX86} asm файла procedure Move(const Source; var Dest; Count: NativeInt);. Раздел кода добавлен ниже. Строка FILD QWORD PTR [EAX] {Last 8}.

Мы предполагаем, что проблема связана с тем, как наше приложение справляется с управлением памятью в Windows 7, но мы не знаем, как выяснить, где что-то идет не так. Образец стека вызовов прилагается.

Может ли кто-нибудь предложить, как мы могли бы приступить к устранению этой проблемы? Существуют ли сторонние инструменты отладки, которые могли бы помочь? Существуют ли инструменты Delphi IDE, которые мы можем использовать, чтобы попытаться отследить это? Статьи, которые могут быть полезны?

Большое спасибо за любые предложения.

Вот раздел кода System.pas, где происходят аудио/видеозаписи:

    @@LargeForwardMove: {4-Byte Aligned}
    PUSH    EDX
    FILD    QWORD PTR [EAX] {First 8}
    LEA     EAX, [EAX+ECX-8]
    LEA     ECX, [ECX+EDX-8]
    FILD    QWORD PTR [EAX] {Last 8}      // <- Debug break pointer will be here. 
    PUSH    ECX
    NEG     ECX
    AND     EDX, -8 {8-Byte Align Writes}
    LEA     ECX, [ECX+EDX+8]
    POP     EDX

А вот пример из стека вызовов:

vcl.Vcl.Buttons.TBitBtn.Click
vcl.Vcl.StdCtrls.TCustomButton.CNCommand(???)
vcl.Vcl.Controls.TControl.WndProc((48401, 3186, 724082, 0, 3186, 0, (), 3186, 11, (), 0, 0, ()))
vcl.Vcl.Controls.TWinControl.WndProc((48401, 3186, 724082, 0, 3186, 0, (), 3186, 11, (), 0, 0, ()))
vcl.Vcl.StdCtrls.TButtonControl.WndProc((48401, 3186, 724082, 0, 3186, 0, (), 3186, 11, (), 0, 0, ()))
vcl.Vcl.Controls.TControl.Perform(???,???,724082)
vcl.Vcl.Controls.DoControlMsg(???,(no value))
vcl.Vcl.Controls.TWinControl.WMCommand((273, (), 3186, 0, (), 724082, 0))
vcl.Vcl.Controls.TControl.WndProc((273, 3186, 724082, 0, 3186, 0, (), 3186, 11, (), 0, 0, ()))
vcl.Vcl.Controls.TWinControl.WndProc((273, 3186, 724082, 0, 3186, 0, (), 3186, 11, (), 0, 0, ()))
vcl.Vcl.Controls.TWinControl.MainWndProc(???)
rtl.System.Classes.StdWndProc(987008,273,3186,724082)
:772462fa ; C:\Windows\syswow64\USER32.dll
:77246d3a USER32.GetThreadDesktop + 0xd7
:77246de8 ; C:\Windows\syswow64\USER32.dll
:77246e44 ; C:\Windows\syswow64\USER32.dll
:77ad010a ntdll.KiUserCallbackDispatcher + 0x2e
:772496c5 USER32.SendMessageW + 0x4c
:75184601 ; C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2\comctl32.dll
:75184663 ; C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2\comctl32.dll
:751844ed ; C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2\comctl32.dll
:772462fa ; C:\Windows\syswow64\USER32.dll
:77246d3a USER32.GetThreadDesktop + 0xd7
:77250d27 USER32.GetClientRect + 0xc5
:77250d4d USER32.CallWindowProcW + 0x1b
vcl.Vcl.Controls.TWinControl.DefaultHandler(???)
:5046777f TWinControl.DefaultHandler + $EB
:5046766e TWinControl.WndProc + $5CA
:50487a69 TButtonControl.WndProc + $71
:501749c6 StdWndProc + $E
:772462fa ; C:\Windows\syswow64\USER32.dll
:77246d3a USER32.GetThreadDesktop + 0xd7
:772477c4 ; C:\Windows\syswow64\USER32.dll
:7724788a USER32.DispatchMessageW + 0xf

person sdaberle    schedule 05.04.2014    source источник


Ответы (1)


Это похоже на простую ошибку в вашей программе. Возможно обращение к памяти после выпуска. Или переполнение буфера. Что вам нужно сделать, так это некоторую отладку. Вам понадобятся следующие инструменты:

  1. Опция компилятора проверки диапазона включена. Это находит большинство переполнений буфера.
  2. Полная версия FastMM с полными настройками отладки. Это должно выявить такие ошибки, как доступ после бесплатного доступа.
  3. madExcept. Это обеспечит трассировку стека в точке исключения. Это очень важно, потому что позволяет увидеть, как вы дошли до этой точки в коде. Это, в свою очередь, помогает вам увидеть, какие данные передаются, и должно дать вам подсказки относительно того, что вы сделали неправильно. Я знаю, что у вас есть трассировка стека, но она выглядит неправильно. В конце концов, TBitBtn.Click не вызывает Move напрямую.

Не обманывайте себя тем, что тот факт, что вы не видите ошибки в XP, каким-то образом означает, что вина лежит на ОС. Или что как-то нужно по разному обращаться с памятью в разных версиях ОС. Многие ошибки прикладного программирования в одних системах безобидны, но проявляются в других. Высока вероятность того, что ваша программа не работает везде, но вам случайно иногда это сходит с рук.

person David Heffernan    schedule 05.04.2014