Вываливается ошибка "pure virtual function call"
От: BlackKhan  
Дата: 15.11.04 16:43
Оценка:
У заказчика при работе моего сервиса периодически вываливается ошибка "pure virtual function call".

Event Type: Information
Event Source: Application Popup
Event Category: None
Event ID: 26
Date: 13.11.2004
Time: 15:51:46
User: N/A
Computer: IPSOFT2
Description:
Application popup: Microsoft Visual C++ Runtime Library : Runtime Error!

Program: C:BillingIPSoftRadiusRadius.exe

R6025
— pure virtual function call

Причем в логе самого сервиса никаких сообщение об ошибках не появляется. По-видимому, намертво валится один из потоков, не успевая даже ничего отписать.

Сравнил dll на его машине со своими:
1. У него mvvcrt той же версии (7.0), но более поздний build.
2. Одна из моих dll (используется сервисом) более старая. dll экспортирует только одну функцию — создать объект, который является потомком базового класса. Тут казалось бы и ответ, но смущает следующее: классы старой и новой версии отличаются только реализацией одной функции. Как в этом случае может появиться такая ошибка не понимаю.
Кроме того: переписал обе dll с его машины — у меня сервис работает нормально.

Объект ответственный, поэтому эксперементировать не могу (сейчас откатились к пред. версии сервиса). Перед повторной попыткой обновления хотелось бы быть уверенным, что обновление dll решит проблему, в чем я пока сомневаюсь.

Если есть мысли о причине такой ошибки, буду очень признателен!
Re: Вываливается ошибка "pure virtual function call"
От: Кодт Россия  
Дата: 15.11.04 18:29
Оценка:
Здравствуйте, 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.h

struct 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"
От: SergASh  
Дата: 15.11.04 19:02
Оценка: 28 (2)
Здравствуйте, BlackKhan, Вы писали:

BK>У заказчика при работе моего сервиса периодически вываливается ошибка "pure virtual function call".


Такое может произойти, если при объявлении класса запретить генерировать VMT (при помощи ATL_NO_VTABLE либо __declspec(novtable) -- это одно и то же), и при этом в качестве базового класса указать класс с чисто виртуальными функциями. Даже если в своём классе вы для них напишете реализацию, всё равно вызваны будут чисто виртуальные. Попробуйте выбросить ATL_NO_VTABLE в подозрительных местах.
Re: Вываливается ошибка "pure virtual function call"
От: BlackKhan  
Дата: 15.11.04 19:18
Оценка:
Спасибо всем отклюкнувшимся!

Причина точно не в ATL_NO_VTABLE, это не используется т.к. проект собирается под Win32 и Linux.

Штатный способ получить такую ошибку — вызвать из конструктора/деструктора абстрактный метод косвенным способом

Это вряд ли, код достаточно отлажен.

Нештатным способом этого можно добиться — удачно расстреляв память

Вот это и смущает. Может оказаться, что dll и ни причем. Ладно, повременю пока обновлять, сначала еще погоняю на баги.
Re[2]: Вываливается ошибка "pure virtual function call"
От: Alex Alexandrov США  
Дата: 21.11.04 15:34
Оценка:
Здравствуйте, 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)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.