Re[8]: Бага в CoUninitialize
От: Константин Л. Франция  
Дата: 19.09.06 08:17
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Здравствуйте, Vi2, Вы писали:


КД>>>Дык это, того — CoUninitialize это завершение работы. Это его основное назначение. То что он, извините, во время деинициализации сам себе наступает на ..., то это его проблема. Причем очевидно, что он выполняет деинициализацию в неправильном порядке — сначало нужно освободить COM-объекты, потом выгружать DLL.


Vi2>>Это заблуждение: CoUninitialize — это не завершение работы.


КД>Я просто не стал распинаться по этому поводу


КД>>>Кстати говоря, ведь COM может держать не только объект ошибки, но и другие COM-объекты. Есть же функции регистрации активных ActiveX объектов (их названия сходу я не скажу). И что? Я более чем уверен — освобождение этих ActiveX-ов выполняется перед выгрузкой DLL-ей. Потому что иначе вообще любая более менее сложная программа основанная на COM завершалась бы по AV.


Vi2>>В том-то и дело, что "объект ошибки и другие COM-объекты" ничем не отличаются. Вернее, отличаются только тем, кто реализовал код поддержки. И как криво. Поэтому это может быть не баг в CoUninitialize, а баг в обработчике ошибок DB и тому подобное. И может быть продулирован в их, DB, разделе для борьбы с надоедливым AV.


КД>Чего-то ты сам себе противоречишь. И я прям удивляюсь твоему упорству признать, что клоун, реализовываший деинициализацию не подумал, что объект ошибки может быть реализован в другой DLL.


КД>Предлагаю написать баг-репорт в микрософт и посмотреть что они скажут по этому поводу. Я правда не знаю в какую дверь надо стучаться


тебе говорят о том, что oledb32.dll Не должна была выгружаться, пока есть живые ссылки на любой интерфейс, ею реализуемый, даже наследник IErrorInfo . Те баг скорее в oledb32.dll, чем в CoUninit... тк в ней, похоже, неправильно реализован module lock

И еще. Кто и где обещал следить за временем жизни реализаций IErrorInfo? Это обычный интерфейс и будь добр следить за refcount самому
Re: Бага в CoUninitialize при работе с OLEDB-провайдерами
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 19.09.06 08:19
Оценка:
Пропуская текст моего изумления, просто спрошу — а чего это найденную мною багу в поддержке COM связали с багой в обвязке OLEDB.

Я конечно не охеренный спец по всему COM-у, но в состоянии определить кто и за что отвечает. Потому что, грубо говоря, сожрал ни одну собаку в этом деле. В том числе, писал и собственный менеджер DLL-ных COM-серверов. Поэтому более чем хорошо себе представляю то, о чем я тут пишу.

Так что верните название темы взад!

Блин, это все равно что багу в любой библиотеке начинать сваливать на приложение, которое эту библиотеку использует.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[8]: Бага в CoUninitialize
От: Vi2 Удмуртия http://www.adem.ru
Дата: 19.09.06 08:19
Оценка:
Здравствуйте, Лазар Бешкенадзе, Вы писали:

ЛБ>Чтобы было нечто конкретное, что можно обсуждать я берусь реализовать код ошибки и предлагаю определить тензор его кривизны:


Нужно в QueryInterface добавить прирост счетчика. А так — ничего, работать будет.

Но если добавить еще функциональный объект, то могут возникнуть проблемы, т.к. этот объект (ErrorObject) не будет держать DLL сервер.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[9]: Бага в CoUninitialize
От: Лазар Бешкенадзе СССР  
Дата: 19.09.06 08:30
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Здравствуйте, Лазар Бешкенадзе, Вы писали:


ЛБ>>Чтобы было нечто конкретное, что можно обсуждать я берусь реализовать код ошибки и предлагаю определить тензор его кривизны:


Vi2>Нужно в QueryInterface добавить прирост счетчика.


Действительно, ошибочка вышла. Делаю вторую попытку.

#define _WIN32_WINNT 0x0400

#include <msxml2.h>

class ErrorObject : IErrorInfo
{
    LONG m_cRef;
    IXMLDOMDocument *m_pXml;

    ErrorObject() : m_cRef(1) {
        ::CoCreateInstance(__uuidof(DOMDocument), 0, CLSCTX_INPROC_SERVER, __uuidof(IXMLDOMDocument), (void **) &m_pXml);
    }
    ~ErrorObject() {
        if (m_pXml != 0)
            m_pXml->Release();
    }

    HRESULT __stdcall QueryInterface(REFIID iid, void **ppvObject) {
        if (iid == __uuidof(IErrorInfo) || iid == __uuidof(IUnknown)) {
            ErrorObject::AddRef();
            *ppvObject = this;
            return S_OK;
        }
        else {
            *ppvObject = 0;
            return E_NOINTERFACE;
        }
    }
    ULONG __stdcall AddRef(void) { return ::InterlockedIncrement(&m_cRef); }
    ULONG __stdcall Release(void) {
        LONG cRef = ::InterlockedDecrement(&m_cRef);
        if (cRef == 0)
            delete this;
        return cRef;
    }

    HRESULT __stdcall GetGUID(GUID *pGUID) {
        *pGUID = GUID_NULL;
        return S_OK;
    }
    HRESULT __stdcall GetSource(BSTR *pBstrSource) {
        *pBstrSource = 0;
        return S_OK;
    }
    HRESULT __stdcall GetDescription(BSTR *pBstrDescription) {
        *pBstrDescription = 0;
        return S_OK;
    }
    HRESULT __stdcall GetHelpFile(BSTR *pBstrHelpFile) {
        *pBstrHelpFile = 0;
        return S_OK;
    }
    HRESULT __stdcall GetHelpContext(DWORD *pdwHelpContext) {
        *pdwHelpContext = 0;
        return S_OK;
    }

public:
    static HRESULT CreateInstance(IErrorInfo **ppErrorInfo) {
        *ppErrorInfo = new ErrorObject();
        return S_OK;
    }
};

int main()
{
    ::CoInitializeEx(0, COINIT_MULTITHREADED);

    IErrorInfo *pError;
    ErrorObject::CreateInstance(&pError);
    ::SetErrorInfo(0, pError);
    pError->Release();

    ::CoUninitialize();
}


Vi2> А так — ничего, работать будет.


Так не работает. Access Violation!

Vi2>Но если добавить еще функциональный объект, то могут возникнуть проблемы, т.к. этот объект (ErrorObject) не будет держать DLL сервер.


Можно тут поподробнее?

Лазар
Re[9]: Бага в CoUninitialize
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 19.09.06 08:36
Оценка: -1
Здравствуйте, Константин Л., Вы писали:

КД>>Чего-то ты сам себе противоречишь. И я прям удивляюсь твоему упорству признать, что клоун, реализовываший деинициализацию не подумал, что объект ошибки может быть реализован в другой DLL.


КД>>Предлагаю написать баг-репорт в микрософт и посмотреть что они скажут по этому поводу. Я правда не знаю в какую дверь надо стучаться


КЛ>тебе говорят о том, что oledb32.dll Не должна была выгружаться, пока есть живые ссылки на любой интерфейс, ею реализуемый, даже наследник IErrorInfo . Те баг скорее в oledb32.dll, чем в CoUninit... тк в ней, похоже, неправильно реализован module lock


КЛ>И еще. Кто и где обещал следить за временем жизни реализаций IErrorInfo? Это обычный интерфейс и будь добр следить за refcount самому


Слушайте, бросайте курить дурь за компьютером. Это очень вредно для неокрепших мозгов.

oledb32.dll как и любая DLL себя не выгружает! И не загружает! DLL — это пассивное существо. Тем более DLL, которая обслуживает COM-сервера. Берем Рихтера "Windows для этих" и читаем главу про динамические библиотеки. Потом "Основы COM" Роджерсона и читаем что там написано про DLL.

Специально для тугодумов.

1. Загрузите руками любую DLL. Через LoadLibrary
2. Получите адрес любой фукнции из этой DLL, которую вы сможете вызывать.
3. Выгрузите DLL. Через FreeLibrary
4. Вызовите функцию, которую вы получили в пунте два.

AV? И конечно же виновата DLL — я же держу указатель на неё функцию. Чего это она себя выгрузила!
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[10]: Бага в CoUninitialize
От: Vi2 Удмуртия http://www.adem.ru
Дата: 19.09.06 09:04
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

Vi2>>Хорошо. Предположим, этот клоун все же подумал об этом. Какие действия функция CoUninitialize должна совершить в свете этих новых знаний/дум? Простой Release на указателе. Но это ясно и БЕЗ информации о том, где расположен сервер.

КД>Я не догнал — какую информацию ты имеешь в виду.

Предположим, есть явное место, содержащее указатель на активный объект ошибок, т.е. IErrorInfo * pCurrentError. CoUninitialize, как умная Маша, должна освободить этот указатель. Какое обвинение можно предъявить автору/содеру CoUninitialize, если первое требование СОМа — отсутствие знаний о конкретной реализации кода, стоящего за указателем? Т.е. это не важно какая библиотека реализует код объекта, главное, взаимодействие должно идти по правилам. Итак, что он может сделать еще кроме if(pCurrentError) pCurrentError->Release();? Вот этот Release и может вывалится. Вызовом SetErrorInfo(0,NULL) ты помогаешь обойти этот взрывоопасный вызов Release. Но у меня язык не повернется сказать, что приведенный код есть ошибка или что в нем есть потенциальная ошибка.

А почему вылетает Release() — этот вопрос не в компетенции CoUninitialize. Наверное, потому что какой-то поток, освободив объекты в oledb.dll и вызвав правильный CoUninitialize, выгрузил oledb.dll, т.к. она ответила S_OK из DllCanUnloadNow(), потому что других объектов, кроме объекта-ошибки, в ней нет, а объект-ошибка может и не держать ее.

Но я не в курсе объектной модели oledb.dll и применительно к базам данных, поэтому могу ошибаться. Я слышал, что там многое кэшируется для удобства повторного использования. Наверное, слишком кэшируют.

КД>Куда именно она уйдет? С какого перепугу? Еще раз


Ну ведь она ушла! Ты сам писал, что ни твоей DLL, ни oledb.dll уже нет. Хотя я что-то стал сомневаться, что объект живет именно в oledb.dll. Там много мест, в которых он может жить.

КД>Я в упор не вижу где я тут и чему противоречу.


Я и не говорю, что ты чему-то противоречишь. Просто нужно докопать до логического конца.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[10]: Бага в CoUninitialize
От: Vi2 Удмуртия http://www.adem.ru
Дата: 19.09.06 09:10
Оценка:
Здравствуйте, Лазар Бешкенадзе, Вы писали:

Vi2>> А так — ничего, работать будет.

ЛБ>Так не работает. Access Violation!

Действительно, не работает. У меня сообщения не было, но я посмотрел в лог, чтобы убедиться. Так это проблема не в объекте ErrorObject, а в IXMLDOMDocument *m_pXmlDoc. Так что я правильно предположил, что дело не в oledb.dll. У меня показывает, что библиотеки msxml3.dll и shlwapi.dll благополучно смылись во время CoUninitialize.

Vi2>>Но если добавить еще функциональный объект, то могут возникнуть проблемы, т.к. этот объект (ErrorObject) не будет держать DLL сервер.

ЛБ>Можно тут поподробнее?

Поместил ты объект в DLL-ку, которая выгружается по требованию DllCanUnloadNow. Если не предусмотреть возврат S_FALSE при живом ErrorObject, то DLL может быть выгружена, если поток, использующий функциональный объект, закончит работу с этим объектом и вызовет функцию CoFreeUnusedLibraries по тем или иным причинам.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[10]: Бага в CoUninitialize
От: Константин Л. Франция  
Дата: 19.09.06 09:31
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Здравствуйте, Константин Л., Вы писали:


слышь ты, хами друзьям своим

КД>Слушайте, бросайте курить дурь за компьютером. Это очень вредно для неокрепших мозгов.


КД>oledb32.dll как и любая DLL себя не выгружает! И не загружает! DLL — это пассивное существо. Тем более DLL, которая обслуживает COM-сервера. Берем Рихтера "Windows для этих" и читаем главу про динамические библиотеки. Потом "Основы COM" Роджерсона и читаем что там написано про DLL.


и где это я писал, что она сама себя выгружает?
не тупи, если DllCanUnloadNow вернет TRUE, то COM ее выгрузит.

КД>Специально для тугодумов.


сразу виден уровень развития....

КД>1. Загрузите руками любую DLL. Через LoadLibrary

КД>2. Получите адрес любой фукнции из этой DLL, которую вы сможете вызывать.
КД>3. Выгрузите DLL. Через FreeLibrary
КД>4. Вызовите функцию, которую вы получили в пунте два.

КД>AV? И конечно же виновата DLL — я же держу указатель на неё функцию. Чего это она себя выгрузила!
Re[2]: Бага в CoUninitialize при работе с OLEDB-провайдерами
От: Vi2 Удмуртия http://www.adem.ru
Дата: 19.09.06 09:40
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Пропуская текст моего изумления, просто спрошу — а чего это найденную мною багу в поддержке COM связали с багой в обвязке OLEDB.


Да, дело не в обвязке OLEDB. А именно в:

КД>3. При вызове CoUninitialize, сначала выгружаются все библиотеки с COM-объектами (в том числе моя и oledb32.dll), а потом освобождается объект ошибки.


причем я применил пример Лазара Бешкенадзе, но заменил на свою DLL. Так вот при входе в CoUninitialize, идет запрос на освобождение библиотек и, несмотря на то, что я возвращаю S_FALSE, моя библиотека выгружается. И потом идет запрос на освобождение объекта-ошибки.

КД>Я конечно не охеренный спец по всему COM-у, но в состоянии определить кто и за что отвечает. Потому что, грубо говоря, сожрал ни одну собаку в этом деле. В том числе, писал и собственный менеджер DLL-ных COM-серверов. Поэтому более чем хорошо себе представляю то, о чем я тут пишу.


КД>Так что верните название темы взад!


Присоединяюсь. Это не зависит от провайдера.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[11]: Бага в CoUninitialize
От: Лазар Бешкенадзе СССР  
Дата: 19.09.06 09:43
Оценка: 8 (2)
Здравствуйте, Vi2, Вы писали:

Vi2>Здравствуйте, Лазар Бешкенадзе, Вы писали:


Vi2>>> А так — ничего, работать будет.

ЛБ>>Так не работает. Access Violation!

Vi2>Действительно, не работает. У меня сообщения не было, но я посмотрел в лог, чтобы убедиться. Так это проблема не в объекте ErrorObject, а в IXMLDOMDocument *m_pXmlDoc. Так что я правильно предположил, что дело не в oledb.dll. У меня показывает, что библиотеки msxml3.dll и shlwapi.dll благополучно смылись во время CoUninitialize.


Так именно в этом проблема. Мне что-то совершенно не хочется ручками реализовывать целиком DLL,
а если воспользуюсь ATL, мне, конечно, скажут, что виновата ATL, а не CoUninitialize. А эта,
последняя, судя по всему, вовсе не спрашивает DllCanUnloadNow, а просто берет и выгружает.
Причем выгружает до того, как делает Release на объекте ошибки. Что ясно видно под отладчиком.
Но мне, собственно, не важно спрашивают ли они DllCanUnloadNow, да я и не намерен пользоваться
этими DLL после CoUninitialize, но ребенку должно быть очевидно, что Release на объекте ошибки
надо делать до выгрузки DLL, а не до, как это наблюдается.

Vi2>>>Но если добавить еще функциональный объект, то могут возникнуть проблемы, т.к. этот объект (ErrorObject) не будет держать DLL сервер.

ЛБ>>Можно тут поподробнее?

Vi2>Поместил ты объект в DLL-ку, которая выгружается по требованию DllCanUnloadNow. Если не предусмотреть возврат S_FALSE при живом ErrorObject, то DLL может быть выгружена, если поток, использующий функциональный объект, закончит работу с этим объектом и вызовет функцию CoFreeUnusedLibraries по тем или иным причинам.


Ну так я же и не брался реализовывать DllCanUnloadNow, и не помещал свой класс в библиотеку,
да и факторию для него не делал. Предлагаю журналу RSDN сделать все это и отчитаться перед
товарищами за проделанную работу.

Лазар
Re[12]: Бага в CoUninitialize
От: Константин Л. Франция  
Дата: 19.09.06 10:02
Оценка:
Здравствуйте, Лазар Бешкенадзе, Вы писали:

ЛБ>Здравствуйте, Vi2, Вы писали:


Vi2>>Здравствуйте, Лазар Бешкенадзе, Вы писали:


Vi2>>>> А так — ничего, работать будет.

ЛБ>>>Так не работает. Access Violation!

Vi2>>Действительно, не работает. У меня сообщения не было, но я посмотрел в лог, чтобы убедиться. Так это проблема не в объекте ErrorObject, а в IXMLDOMDocument *m_pXmlDoc. Так что я правильно предположил, что дело не в oledb.dll. У меня показывает, что библиотеки msxml3.dll и shlwapi.dll благополучно смылись во время CoUninitialize.


ЛБ>Так именно в этом проблема. Мне что-то совершенно не хочется ручками реализовывать целиком DLL,

ЛБ>а если воспользуюсь ATL, мне, конечно, скажут, что виновата ATL, а не CoUninitialize. А эта,
ЛБ>последняя, судя по всему, вовсе не спрашивает DllCanUnloadNow, а просто берет и выгружает.
ЛБ>Причем выгружает до того, как делает Release на объекте ошибки. Что ясно видно под отладчиком.
ЛБ>Но мне, собственно, не важно спрашивают ли они DllCanUnloadNow, да я и не намерен пользоваться
ЛБ>этими DLL после CoUninitialize, но ребенку должно быть очевидно, что Release на объекте ошибки
ЛБ>надо делать до выгрузки DLL, а не до, как это наблюдается.

ИМХО, вызов DllCanUnloadNow совершенно бессмыслен внутри CoUninit.., тк не имеет смысла внутри ее ждать, пока все библиотеки готовы выгрузиться.
А в целом, согласен, баг явный.

[]
Re[11]: Бага в CoUninitialize
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 19.09.06 10:21
Оценка: 3 (1)
Здравствуйте, Vi2, Вы писали:

Ну, судя по ответам которые пришли пока я бился головой об стол, разобрались. А то у мне осталось только упасть под стол и забился в конвульсиях от чтения ответов в этой ветке.

Я рад, что все рады.



Vi2>Предположим, есть явное место, содержащее указатель на активный объект ошибок, т.е. IErrorInfo * pCurrentError. CoUninitialize, как умная Маша, должна освободить этот указатель. Какое обвинение можно предъявить автору/содеру CoUninitialize, если первое требование СОМа — отсутствие знаний о конкретной реализации кода, стоящего за указателем? Т.е. это не важно какая библиотека реализует код объекта, главное, взаимодействие должно идти по правилам. Итак, что он может сделать еще кроме if(pCurrentError) pCurrentError->Release();? Вот этот Release и может вывалится.

Так, давайте-ка вернемся к тому с чего мы начинали.

Напоминаю, внутри CoUninitialize происходит AV. Как показали иследования, AV происходит только в том случае если была установлен объект-ошибки с нестандартной реализацией. И эта реализация находится в DLL-и оформленной как COM-сервер.

AV не может происходить только потому что внутри COM висит объект ошибки. Значит с ним что-то делают. Что могут делать с указателем на COM-объект при деинициализации? Все правильно — для него вызывают Release. Но перед этим были выгружены DLL-и COM-серверов.

И поэтому pCustomeErorr->Release() не "может вываливаться", а именно вываливается по AV.

Vi2>Вызовом SetErrorInfo(0,NULL) ты помогаешь обойти этот взрывоопасный вызов Release. Но у меня язык не повернется сказать, что приведенный код есть ошибка или что в нем есть потенциальная ошибка.


Vi2>А почему вылетает Release() — этот вопрос не в компетенции CoUninitialize.

Кот сидит и орет. У него спрашивают
 - чего орешь-то?
 - я сел себе на ... 
 - так встань!
 - не хочу.

Конечно не в его. За то что в CoUninitialize левая рука вызвала FreeLibrary для DLL-ей COM-серверов, правая рука CoUninitialize не отвечает.

Vi2>Наверное, потому что какой-то поток, освободив объекты в oledb.dll и вызвав правильный CoUninitialize, выгрузил oledb.dll, т.к. она ответила S_OK из DllCanUnloadNow(), потому что других объектов, кроме объекта-ошибки, в ней нет, а объект-ошибка может и не держать ее.


Знаешь, проверять в падлу, но гарантирую — DllCanUnloadNow внутри CoUninitialize не вызывается. Потому что наличие активных объектов в выгружаемых DLL-ях CoUninitialize абсолютно не интересует. Это раз. А во вторых, даю гарантию что объект-ошибки, как в прочем и фабрики классов (которые вроде как являются служебными COM-объектами) увеличивают счетчик COM-блокировок DLL-и. Именно COM-блокировок, которые анализируются в DllCanUnloadNow, а не тех блокировок DLL, которые увеличиваются при вызове LoadLibrary и уменьшаются при FreeLibrary.

<вырезано>

Vi2>Я и не говорю, что ты чему-то противоречишь. Просто нужно докопать до логического конца.


Конец заключается в том, что CoUnitialize должен освобождать объект ошибки (который он все равно освобождает) до того как начнет вызывать FreeLibrary для DLL-ей с COM-серверами загруженными в текущем потоке.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[11]: Бага в CoUninitialize
От: Ivan Россия www.rsdn.ru
Дата: 19.09.06 10:26
Оценка: +2
Здравствуйте, Vi2, Вы писали:

Vi2> Итак, что он может сделать еще кроме if(pCurrentError) pCurrentError->Release();?

может вызвать его не вовремя, когда нужный модуль уже выгрузился. Во время вызова CoUninitialize DllCanUnload уже вряд ли способен на что-то повилять — dll выгружаются форсированно, а код CoUninitialize может быть написан так, что освобождает обхект ошибки после форсированной выгрузки остальных модулей (рассчитывая, что объект ошибки "проживает" в ole32.dll) — вот и грабли.
Re[12]: Бага в CoUninitialize
От: Vi2 Удмуртия http://www.adem.ru
Дата: 19.09.06 11:49
Оценка: 5 (1) +1
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Знаешь, проверять в падлу, но гарантирую — DllCanUnloadNow внутри CoUninitialize не вызывается.


Вызывается. Но потом, наверное, идет контрольный CoFreeAllLibraries.

КД>Конец заключается в том, что CoUnitialize должен освобождать объект ошибки (который он все равно освобождает) до того как начнет вызывать FreeLibrary для DLL-ей с COM-серверами загруженными в текущем потоке.


Возможно было бы правильнее, если в начале CoUnitialize объект-ошибка был освобожден принудительно, как ты делаешь перед его вызовом. Но освобождаться окончательно он должен в самом конце, т.к. во время выгрузки СОМ inproc-серверов могут быть СОМ вызовы и есть вероятность, что объект-ошибка может снова появится. Поэтому он и не освобождается из-за оптимизации. Да, круто замешано.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[13]: Бага в CoUninitialize
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 19.09.06 12:18
Оценка:
Здравствуйте, Vi2, Вы писали:

КД>>Знаешь, проверять в падлу, но гарантирую — DllCanUnloadNow внутри CoUninitialize не вызывается.


Vi2>Вызывается.


Но это уже никого не спасает от последующей выгрузки.

КД>>Конец заключается в том, что CoUnitialize должен освобождать объект ошибки (который он все равно освобождает) до того как начнет вызывать FreeLibrary для DLL-ей с COM-серверами загруженными в текущем потоке.


Vi2>Возможно было бы правильнее, если в начале CoUnitialize объект-ошибка был освобожден принудительно, как ты делаешь перед его вызовом. Но освобождаться окончательно он должен в самом конце, т.к. во время выгрузки СОМ inproc-серверов могут быть СОМ вызовы и есть вероятность, что объект-ошибка может снова появится. Поэтому он и не освобождается из-за оптимизации. Да, круто замешано.


Не помню кто именно, ... хотя вот, нашел
Автор: korzhik
Дата: 20.06.06
этот документ с рекомендациями по созданию DLL. Сам пока не читал — но скоро прийдется вникать в его содержимое

Формально, конечно есть потенциальные грабли, когда при выгрузке DLL она возьмет и зарегистрирует объект-ошибку. Которую к тому же сама же и реализует. Но тут уж явно засада будет в этой DLL, а не CoUnitialize

Лично мне больше нравятся грабли связанные с COM и такими разделяемыми ресурсами как управляющий флаг сопроцессора. Реально ощущаешь всю тщетность бытия.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[8]: Бага в CoUninitialize
От: Left2 Украина  
Дата: 19.09.06 15:38
Оценка:
КД>>>Но рекомендую бросать молится на тех, кто сидит в MS. Я встречал у них баги и пострашнее, чем этот несчастный CoUnitialize.
КЛ>>дык, никто и не молится
А>Не правда ваша, многие как раз. А почему — действительно непонятно. Когда-то — да, каждый из нескольких десятков программеров работавших в МС был профи, теперь это тысячи индусов и русских закончивших институт год-два-три назад, ещё ничему не научившихся и способных делать любые глупейшие ошибки. Хорошо хоть тестеров там больше чем кодеров.
А>ИМХО — БГ от этого и бежит. ИМХО: они ошиблись в том, что подумали что набрав тысячи програмеров они смогут свернуть горы. Годах в 96-98 набрали — результат плачевный — больше никогда и ничего не смогли сделать в срок даже близко (Vista — апофеоз) и хотя бы с 50% запланированного функционала. НТ тим был вроде 50 человек и сделали его "играючи". 2к тим был вроде 2000 програмеров + 3000 тестеров — еле-еле сделали не уложившись в сроки в 2-3 раза (он же НТ 5 должен был зваться и выйти в 97-98). ИМХО: оригинальный НТ тим легко сделал бы в срок. Сверхприбылей уже нет — всё явно съедает эта толпа програмеров. Права на бизнес-ошибку (коих в истории майкрософта навалом) больше нет — нет денежного резерва как раньше, когда доходы сильно превышали расходы. И выгнать всю эту толпу никак — не простит биржа, трудовое законодательство, да и самим обидно.

Не скажу что ты неправ в корне, но ты ИМХО смотришь на проблему однобоко. А именно, забываешь о немерянном грузе совместимости, который МС тянет за собой. Помнишь, как во времена 95 и NT народ держал у себя на машине 2 системы — NT для того чтобы педалить серьёзные программы под винду и 95(98) для того чтобы иметь возможность запускать старые досовские игрухи и приложения? Ты почитай про то как майкрософтовцы мучались, заставляя работать старые досовские программы под 95 — как писали в системе workaround-ы вокруг багов, которые были в самих досовских приложениях... А это огромный кусок работы. А когда выходила 2000-я — пришлось держать обратную совместимость и с NT тоже. И этот груз совместимости просто захлестнул MS — задача создания новой операционки, на которой будут работать большинство старых программ становится абсолютно неподьёмной. Поменять что-то кардинально в архитектуре сейчас архисложно — вспомни хотя бы их попытку переписать весь Win32 на .Net и как они благополучно предпочли о ней забыть когда поняли что задача просто нереальна.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: Бага в CoUninitialize
От: Константин Л. Франция  
Дата: 19.09.06 15:42
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Константин Л., Вы писали:


КД>>>Но рекомендую бросать молится на тех, кто сидит в MS. Я встречал у них баги и пострашнее, чем этот несчастный CoUnitialize.

КЛ>>дык, никто и не молится

я про себя

А>Не правда ваша, многие как раз. А почему — действительно непонятно. Когда-то — да, каждый из нескольких десятков программеров работавших в МС был профи, теперь это тысячи индусов и русских закончивших институт год-два-три назад, ещё ничему не научившихся и способных делать любые глупейшие ошибки. Хорошо хоть тестеров там больше чем кодеров.

А>ИМХО — БГ от этого и бежит. ИМХО: они ошиблись в том, что подумали что набрав тысячи програмеров они смогут свернуть горы. Годах в 96-98 набрали — результат плачевный — больше никогда и ничего не смогли сделать в срок даже близко (Vista — апофеоз) и хотя бы с 50% запланированного функционала. НТ тим был вроде 50 человек и сделали его "играючи". 2к тим был вроде 2000 програмеров + 3000 тестеров — еле-еле сделали не уложившись в сроки в 2-3 раза (он же НТ 5 должен был зваться и выйти в 97-98). ИМХО: оригинальный НТ тим легко сделал бы в срок. Сверхприбылей уже нет — всё явно съедает эта толпа програмеров. Права на бизнес-ошибку (коих в истории майкрософта навалом) больше нет — нет денежного резерва как раньше, когда доходы сильно превышали расходы. И выгнать всю эту толпу никак — не простит биржа, трудовое законодательство, да и самим обидно.

отвечать в лом
Re[6]: Бага в CoUninitialize
От: Tom Россия http://www.RSDN.ru
Дата: 19.09.06 16:48
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Здравствуйте, Vi2, Вы писали:


Vi2>>Здравствуйте, Коваленко Дмитрий, Вы писали:


Vi2>>Естественно. После вызова SetErrorInfo объект-ошибку можно релизить — ее счетчик на совести СОМ системы. Но почему ушла oledb32.dll, если, ты говоришь, в ней реализован объект-ошибка? Наверное, из-за тог, что приложение завершается. Значит, что-то не так с самим выходом.


КД>Вообще это было злополучное стечение багов. Коротко говоря, у меня при последнем Release внутри компонента возникала ошибка и я радостно пытался сообщить о ней клиенту через объект-ошибку из oledb32.dll. Ясный пень, клиент не будет проверять результаты работы Release, поэтому объект-ошибки продолжал висеть в памяти до деинициализции COM-а.


Тупой баг CoUninitialize, перед выгрузкой ессно надо сделать релиз обьекту ошибки
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Народная мудрось
всем все никому ничего(с).
Re[13]: Бага в CoUninitialize
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 19.09.06 17:48
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Возможно было бы правильнее, если в начале CoUnitialize объект-ошибка был освобожден принудительно, как ты делаешь перед его вызовом. Но освобождаться окончательно он должен в самом конце, т.к. во время выгрузки СОМ inproc-серверов могут быть СОМ вызовы и есть вероятность, что объект-ошибка может снова появится. Поэтому он и не освобождается из-за оптимизации. Да, круто замешано.

Я что придумал на ночь глядя — во время деинициализации COM-а он должен давать отлуп попыткам вызова SetErrorInfo — вуаля
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[8]: Бага в CoUninitialize
От: Лазар Бешкенадзе СССР  
Дата: 20.09.06 11:30
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Здравствуйте, Vi2, Вы писали:


КД>Предлагаю написать баг-репорт в микрософт и посмотреть что они скажут по этому поводу. Я правда не знаю в какую дверь надо стучаться


В эту.

Лазар
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.