Может ли LoadLibrary потереть данные приложения ?
От: drobus  
Дата: 28.02.07 22:18
Оценка:
Екзешник написан на VC6 + MFC. Ошибка возникает при отрисовке графика. Данные хранятся в списке:
std::list< RDOTracerValue* >

, где RDOTracerValue довольно простой класс. Память выделяется под экземпляры через new/delete. Всё работает (отрисовывается) хорошо, до тех пор, пока не будет вызвана LoadLibrary. Для простоты:

HMODULE lib = ::LoadLibrary( "plugins/Project2.dll" );
if ( lib ) {
    ::FreeLibrary( lib );
}


После чего перерисовывается окно с графиком (его данные не изменялись) и вылетает ошибка:
Unhandled exception in <app.exe>: 0xC000008E: Float Divide by Zero

Ошибка так себе, как два пальца,... думал я пока не попытался её исправить. Вот строчка:
bool res = val && (val->modeltime->time >= view->drawFromX.time);

Вот код:
208:              bool res = val && (val->modeltime->time >= view->drawFromX.time);
004523CF   cmp         dword ptr [val],0
004523D3   je          RDOTracerSerie::drawSerie+0D8h (004523f8)
004523D5   mov         eax,dword ptr [ebp+8]
004523D8   mov         ecx,dword ptr [val]
004523DB   mov         edx,dword ptr [ecx]
004523DD   fld         qword ptr [edx]
004523DF   fcomp       qword ptr [eax+0E8h]
004523E5   fnstsw      ax
004523E7   test        ah,1
004523EA   jne         RDOTracerSerie::drawSerie+0D8h (004523f8)
004523EC   mov         dword ptr [ebp-0C4h],1
004523F6   jmp         RDOTracerSerie::drawSerie+0E2h (00452402)
004523F8   mov         dword ptr [ebp-0C4h],0
00452402   mov         al,byte ptr [ebp-0C4h]
00452408   mov         byte ptr [res],al

Указатель стоит на 004523DD.

Помогите разобраться. Ничего не понимаю, и уже не первый день. Как такое могло произойти после загрузки либы ? Пока сам ковырялся установил следующее: программа ссыпется, если либа написана на C++Builder'е (тестил на 5.0 и 6.0) с включенной VCL. Если её отключить, оставить только C++, то всё работает нормально. Если либа написана на VC++6.0 с или без MFC, то тоже проблем нет. Вот код неработающей либы:
//---------------------------------------------------------------------------

#include <vcl.h>
#include <windows.h>
#pragma hdrstop
//---------------------------------------------------------------------------
//   Important note about DLL memory management when your DLL uses the
//   static version of the RunTime Library:
//
//   If your DLL exports any functions that pass String objects (or structs/
//   classes containing nested Strings) as parameter or function results,
//   you will need to add the library MEMMGR.LIB to both the DLL project and
//   any other projects that use the DLL.  You will also need to use MEMMGR.LIB
//   if any other projects which use the DLL will be performing new or delete
//   operations on any non-TObject-derived classes which are exported from the
//   DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
//   EXE's to use the BORLNDMM.DLL as their memory manager.  In these cases,
//   the file BORLNDMM.DLL should be deployed along with your DLL.
//
//   To avoid using BORLNDMM.DLL, pass string information using "char *" or
//   ShortString parameters.
//
//   If your DLL uses the dynamic version of the RTL, you do not need to
//   explicitly add MEMMGR.LIB as this will be done implicitly for you
//---------------------------------------------------------------------------

#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
    return 1;
}
//---------------------------------------------------------------------------

, т.е. это то, что получается после работы Борлондового визарда. Галка VC++ Style DLL погоду не меняет. Вот и возникают у меня подозрения, что даже при пустой DllEntryPoint/DllMain всетаки что-то там в VCL инициализируется, но по странным адресам. Даже не представляю чем это можно проверить. И вообще, что делать. Уже паникую.
Re: Может ли LoadLibrary потереть данные приложения ?
От: drobus  
Дата: 01.03.07 07:37
Оценка:
Обратил внимание, что в случае использования VCL автоматом подгружается C:\WINDOWS\system32\oleaut32.dll.
Re: Может ли LoadLibrary потереть данные приложения ?
От: Какая разница Украина  
Дата: 01.03.07 10:47
Оценка:
Удалено избыточное цитирование. — SchweinDeBurg

Здравствуйте, drobus, Вы писали:

D>Указатель стоит на 004523DD.


Что — же ты людей вводиш в заблуждение

В приведенной строчке и в ассемблерном листинге на эту строчку отсуствует команда деления
Так как может выскочить ошибка деления на 0 если там вообще нет деления
!0xDEAD
Re: Может ли LoadLibrary потереть данные приложения ?
От: Pavel Dvorkin Россия  
Дата: 01.03.07 10:57
Оценка:
Здравствуйте, drobus, Вы писали:

D>004523DD fld qword ptr [edx]


Вопрос — что там в val->modeltime->time находится

а) без DLL
b) с DLL

Желательно сравнить 8 байт как они есть.
With best regards
Pavel Dvorkin
Re: Может ли LoadLibrary потереть данные приложения ?
От: algol Россия about:blank
Дата: 01.03.07 11:09
Оценка:
Здравствуйте, drobus, Вы писали:

D>Помогите разобраться. Ничего не понимаю, и уже не первый день. Как такое могло произойти после загрузки либы ? Пока сам ковырялся установил следующее: программа ссыпется, если либа написана на C++Builder'е (тестил на 5.0 и 6.0) с включенной VCL. Если её отключить, оставить только C++, то всё работает нормально. Если либа написана на VC++6.0 с или без MFC, то тоже проблем нет. Вот код неработающей либы:


У каких-то из старых продукт Борланда (кажется Турбо-Паскаль) была аналогичная проблема с ошибкой деления на 0 на быстрых (для того времени) машинах. Насколько не изменяет склероз, там при инициализации измерялось быстродействие машины, чтобы потом его где-то учитывать. На слишком быстрых машинах время получалось нулевым и возникала ошибка деления.
Возможно здесь аналогичная проблема. Вот здесь например написано:

Description

Some applications (larger ones) written in Delphi 7 will crash at startup if HyperThreading is enabled on fast machines (>=3 GHz). First it appears a "unknown software exception (0xc000008e)" and then a "Runtime error 200".

Workarounds

Disable HyperThreading in BIOS and use a HAL with no "ACPI-Multiprocessor". Then same EXE works fine.

Re[2]: Может ли LoadLibrary потереть данные приложения ?
От: drobus  
Дата: 02.03.07 07:21
Оценка:
Здравствуйте, Какая разница, Вы писали:

D>>Указатель стоит на 004523DD.

КР>Что — же ты людей вводиш в заблуждение
КР>В приведенной строчке и в ассемблерном листинге на эту строчку отсуствует команда деления
КР>Так как может выскочить ошибка деления на 0 если там вообще нет деления

Так в том и дело, что сам не вижу деления ни в исходниках, ни в асме. Но ошибка есть. Причем она возникает в приложении на MFC только после загрузки им либы на VCL. И если либу не грузить, то код работает. Может ли быть такое, что этот код уже потерся либой, а отладчик просто глючит ? Вдруг он показывает не дизассемблер, а то, что сам нагенерил при компиляции. В любом случае проект не пашет, и что с этим делать не совсем понятно. Возможно надо OLE как-то хитро инитить. Вон, VCL его автоматом грузит. Да, и если грузить либу через LoadLibraryEx с флагом DONT_RESOLVE_DLL_REFERENCES, то всё пашет, но этот вариант не приемлем.
Re[2]: Может ли LoadLibrary потереть данные приложения ?
От: drobus  
Дата: 02.03.07 08:07
Оценка:
Здравствуйте, algol, Вы писали:

A>У каких-то из старых продукт Борланда (кажется Турбо-Паскаль) была аналогичная проблема с ошибкой деления на 0 на быстрых (для того времени) машинах. Насколько не изменяет склероз, там при инициализации измерялось быстродействие машины, чтобы потом его где-то учитывать. На слишком быстрых машинах время получалось нулевым и возникала ошибка деления.

A>Возможно здесь аналогичная проблема. Вот здесь например написано:

Спасибо. Как вариант очень даже, но:
1. Пишу этот код на двух машинах: двух-ядерной AMD (3.3 или 3.6 GHz) и одно-ядерной Intel P4(2.4 GHz). Ошибка стабильно повторяется и там и там. При тестировании исходники пересобирал полностью, включая либы на VCL и MFC, проверял версии release/debug. В релизе меняется сообщение об ошибке на:
Исключение unknow software exception (0xc0000090) в приложении по адресу 0x00468ebc

2. Даже если VCL инитит себя при загрузке и отваливается с ошибкой как это можно отловить ?
3. После загрузки могу вызывать код из VCL и наоборот (её передается указатель на самопальный интерфейс) и всё работает хорошо, пока не прошу перерисовать график, который ну никто не менял сознательно.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.