Причем в логе самого сервиса никаких сообщение об ошибках не появляется. По-видимому, намертво валится один из потоков, не успевая даже ничего отписать.
Сравнил dll на его машине со своими:
1. У него mvvcrt той же версии (7.0), но более поздний build.
2. Одна из моих dll (используется сервисом) более старая. dll экспортирует только одну функцию — создать объект, который является потомком базового класса. Тут казалось бы и ответ, но смущает следующее: классы старой и новой версии отличаются только реализацией одной функции. Как в этом случае может появиться такая ошибка не понимаю.
Кроме того: переписал обе dll с его машины — у меня сервис работает нормально.
Объект ответственный, поэтому эксперементировать не могу (сейчас откатились к пред. версии сервиса). Перед повторной попыткой обновления хотелось бы быть уверенным, что обновление dll решит проблему, в чем я пока сомневаюсь.
Если есть мысли о причине такой ошибки, буду очень признателен!
Re: Вываливается ошибка "pure virtual function call"
Здравствуйте, BlackKhan, Вы писали:
BK>Если есть мысли о причине такой ошибки, буду очень признателен!
Штатный способ получить такую ошибку — вызвать из конструктора/деструктора абстрактный метод косвенным способом
struct Foo
{
virtual void foo() = 0;
void bar() { foo(); } // динамический вызов
Foo()
{
foo(); // статический вызов ***
bar(); // приведёт к PVFC
}
};
void Foo::foo() {} // если мы статически вызываем, значит, должны определить
// а если не вызываем (закомментируем строку ***), то в определении не нуждаемся
Причём это может быть как собственный метод, так и метод базового класса.
Нештатным способом этого можно добиться
— удачно расстреляв память
— нарушив ODR (one definition rule) — что вполне вероятно при рассогласованных DLL
Пример нарушения ODR
///////////////////
// foo.hstruct Foo
{
#ifdef FOO_THEN_BAR
virtual void foo() = 0;
virtual void bar() {}
#else
virtual void bar() {}
virtual void foo() = 0;
#endif
Foo();
};
//////////////////
// foo.cpp#define FOO_THEN_BAR
#include"foo.h"
Foo::Foo() {} // VMT содержит: [0]=PVFC, [1]=&Foo::bar
//////////////////
// bar.h#include"foo.h"struct Bar : Foo
{
void buz() { bar(); }
Bar() { buz(); } // кажется, всё в порядке: динамический вызов существующего виртуального метода
};
//////////////////
// buz.cpp
//#define FOO_THEN_BAR#include"bar.h"struct Buz : Bar
{
void foo() {} // чтобы класс был не абстрактным
};
main()
{
Buz trahtibidoh;
// при конструировании базового подобъекта Buz мы нарвёмся на старую VMT (если RTTI выключено и Bar воспользовался VMT предка)
}
Перекуём баги на фичи!
Re: Вываливается ошибка "pure virtual function call"
Здравствуйте, BlackKhan, Вы писали:
BK>У заказчика при работе моего сервиса периодически вываливается ошибка "pure virtual function call".
Такое может произойти, если при объявлении класса запретить генерировать VMT (при помощи ATL_NO_VTABLE либо __declspec(novtable) -- это одно и то же), и при этом в качестве базового класса указать класс с чисто виртуальными функциями. Даже если в своём классе вы для них напишете реализацию, всё равно вызваны будут чисто виртуальные. Попробуйте выбросить ATL_NO_VTABLE в подозрительных местах.
Re: Вываливается ошибка "pure virtual function call"
Здравствуйте, BlackKhan, Вы писали:
B> Спасибо всем отклюкнувшимся! B> B> Причина точно не в ATL_NO_VTABLE, это не используется т.к. проект B> собирается под Win32 и Linux. B> B>
B> Штатный способ получить такую ошибку — вызвать из
B> конструктора/деструктора абстрактный метод косвенным способом
B> Это вряд ли, код достаточно отлажен. B> B>
B> Нештатным способом этого можно добиться — удачно расстреляв память
B> Вот это и смущает. Может оказаться, что dll и ни причем. Ладно, B> повременю пока обновлять, сначала еще погоняю на баги.
Рекомендую также проверить на memory overrun-ы. Например, потестировать дебажный билд или релизный + gflags /p /enable your_app.exe
-- Всего хорошего!
-- Alex Alexandrov, e-mail: alex_alexandrov(at)fromru(dot)com
Posted via RSDN NNTP Server 1.9 gamma
It's kind of fun to do the impossible (Walt Disney)