Екзешник написан на 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 инициализируется, но по странным адресам. Даже не представляю чем это можно проверить. И вообще, что делать. Уже паникую.
Обратил внимание, что в случае использования VCL автоматом подгружается C:\WINDOWS\system32\oleaut32.dll.
Удалено избыточное цитирование. — SchweinDeBurg
Здравствуйте, drobus, Вы писали:
D>Указатель стоит на 004523DD.
Что — же ты людей вводиш в заблуждение
В приведенной строчке и в ассемблерном листинге на эту строчку отсуствует команда деления
Так как может выскочить ошибка деления на 0 если там вообще нет деления
Здравствуйте, 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.
Здравствуйте, Какая разница, Вы писали:
D>>Указатель стоит на 004523DD.
КР>Что — же ты людей вводиш в заблуждение
КР>В приведенной строчке и в ассемблерном листинге на эту строчку отсуствует команда деления
КР>Так как может выскочить ошибка деления на 0 если там вообще нет деления
Так в том и дело, что сам не вижу деления ни в исходниках, ни в асме. Но ошибка есть. Причем она возникает в приложении на MFC только после загрузки им либы на VCL. И если либу не грузить, то код работает. Может ли быть такое, что этот код уже потерся либой, а отладчик просто глючит ? Вдруг он показывает не дизассемблер, а то, что сам нагенерил при компиляции. В любом случае проект не пашет, и что с этим делать не совсем понятно. Возможно надо OLE как-то хитро инитить. Вон, VCL его автоматом грузит. Да, и если грузить либу через LoadLibraryEx с флагом DONT_RESOLVE_DLL_REFERENCES, то всё пашет, но этот вариант не приемлем.
Здравствуйте, 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 и наоборот (её передается указатель на самопальный интерфейс) и всё работает хорошо, пока не прошу перерисовать график, который ну никто не менял сознательно.