На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
[!] Как относитесь к модерированию на этом форуме? Выскажите свое мнение здесь
Модераторы: Qraizer
  
> Что может вызвать ERROR_ALREADY_EXISTS если не файлы? , прошу немного пованговать
    Добрый вечер.
    Прошу прощения за не вполне профессиональное объяснение проблемы, я не достаточно хорошо разбираюсь в С++.

    Есть сложный софт, исходники закрыты, есть только исходники пары модулей один из которых я сейчас переписываю / дорабатываю.
    Грубо говоря все на интерфейсах, сплошные CreateInterface() в библиотеках.

    Интерфейс (класс) который вызывается из основной программы или одного из ее модулей (и который имплементирован в моей DLL) имеет метод Refresh в который одним из параметров является IResponse - класс, содержащий 3 метода: Processed(int i), Failed(int i), Complete(). По мере работы моего метода Refresh я должен сообщать основной программе через IResponse->Processed() индексы прошедших объектов, через Failed - не прошедших, по окончании работы метода уведомить через Complete(). Как-то так было в исходном варианте, да и в моем все то же самое.
    При уведомлении через Processed() приложение запрашивает мой метод GetData где я возвращаю структуру данных заранее известного формата, это все отображается на экране в виде таблицы.

    Основное приложение слишком часто просто зависает до прибивания диспетчером задач, изредка вылетает без никаких MessageBox'ов, по тихому. Что касается вылетов - это в основном было из за багов в коде, переполнений и так далее, вроде бы все пофиксил. Зависания были и в исходном варианте, и сейчас (только я думал что они происходили из-за изначально неграмотной архитектуры и кучи создаваемых даром не нужных потоков, которую собственно и взялся переписывать - но, видимо, не только).

    В процессе вывода дебага нарисовывается такая картина: во первых, после каждого Processed() вызывается GetData для идентификатора от 0 до последнего, иногда не по порядку. Баг это или фича я не знаю, но это в основном приложении, исходников которого я не имею. В результате вместо запроса GetData N раз я получаю его порядка 1+2+3+4+...+N раз, но это не основное.

    При каких-то обстоятельствах вызов Processed завершается ошибкой. В смысле в поисках вылета я закмнул все что мог в __try и обнаружил что после Processed получается GetLastError = 183 (ERROR_ALREADY_EXISTS). То же самое при вызове Complete.

    Пример: проходит первый десяток Processed, после чего на 11-м элементе Processed вылетает с ошибкой 183, после чего все последующие тоже вылетают (а строки таблицы на экране уже не добавляются), в конце вызывается судя по логу Complete, завернутый тоже в __try, он завершается с той же ошибкой и эта строка в логе последняя - далее приложение не отвечает. Впрочем, может быть что GUI не отвечает и раньше но заметить это с точности до полсекунды невозможно.

    В mdmp файле этого процесса Visual Studio расшифровывает как код исключения 0xC0000005, "потоком была принята попытка прочитать или записать данные на виртуальный адрес, к которому он не имеет соответствующего доступа".

    Я точно знаю что данные отображаются только на экране, они не пишутся ни в какие файлы. Кто может вангануть почему может возникать ошибка 183?
    Сообщение отредактировано: Виталь -
      Для начала покажи хотя бы, что представляет из себя интерфейс IResponse. Я так понимаю реализовывал его ты, и, скорее всего, где-то накосячил.
        Цитата Виталь @
        Есть сложный софт, исходники закрыты, есть только исходники пары модулей один из которых я сейчас переписываю / дорабатываю. Грубо говоря все на интерфейсах, сплошные CreateInterface() в библиотеках.


        Эти модули (до переписывания) вызывали проблемы работы основной программы?
          Цитата Виталь @
          Я точно знаю что данные отображаются только на экране, не пишутся ни в какие файлы. Кто может вангануть почему может возникать ошибка 183?

          Во-первых,в файл могут записываться не данные, а, например, тот же лог.
          Во-вторых, ошибка ERROR_ALREADY_EXISTS относится не только к файлам, но и ко многим (если не ко всем) именованным объектам (мьютексам, семафорам, разделяемой памяти и т.д.). Но в большинстве случаев это не ошибка, а просто индикатор того, что такой объект уже существует, т.е. некая Create-функция отрабатывает нормально, но возвращает хэндл не уникального (вновь созданного) объекта, а уже существующего. Поэтому не исключено, что истинная причина ошибки в чем-то другом, а GetLastError = 183 - просто старое значение от успешной Create-операции, не относящееся к делу.
            DLL представляет собой COM-сервер? Апартмент какой? Если не совпадает с требуемым, то по-любому задействуется маршалинг, и код ошибки скорее относится к объектам, создаваемым им самим для своих нужд.
            Вообще, код ошибки в подобных случаях практически бесполезен. Он может относится к операциям, не имеющим никакого отношения к проблеме. Это не то же самое, когда ты вызвал API-функцию, она вернула неуспех, и ты поинтересовался GetLastError(), это вообще неизвестно какая функция неизвестно когда вызванная. Тут нужно применять другие методы поиска причин. Например, procexp посмотреть нитки и стеки, processexplorer собрать подробный журнал API-вызов и операций с объектами. Итп.

            Добавлено
            Цитата Виталь @
            В процессе вывода дебага нарисовывается такая картина: во первых, после каждого Processed() вызывается GetData для идентификатора от 0 до последнего, иногда не по порядку. Баг это или фича я не знаю, но это в основном приложении, исходников которого я не имею. В результате вместо запроса GetData N раз я получаю его порядка 1+2+3+4+...+N раз
            Просто похоже на то, что аппликуха перерисовывает табличку неэффективно, у себя данные не хранит, и потому после отображения каждой новой строки запрашивает все уже отрисованные ранее строки. Если что-то пропускается, значит WM_PAINT припозднилось, и аппликуха успела уйти чуть дальше по алгоритму.
              Цитата Виталь @
              В процессе вывода дебага нарисовывается такая картина: во первых, после каждого Processed() вызывается GetData для идентификатора от 0 до последнего, иногда не по порядку. Баг это или фича я не знаю, но это в основном приложении, исходников которого я не имею. В результате вместо запроса GetData N раз я получаю его порядка 1+2+3+4+...+N раз, но это не основное.
              Похоже на многопоточный доступ, GetData() вызывается более чем из одного потока, из-за этого нарушается порядок, это не баг и не фича... Это типичный механизм.
              Если GetData() не защищена от многопоточного доступа (хотя бы критические секции), то собственно и получается
              Цитата Виталь @
              код исключения 0xC0000005, "потоком была принята попытка прочитать или записать данные на виртуальный адрес, к которому он не имеет соответствующего доступа".
              как результат одновременного доступа из двух потоков к данным.
              Если я не ошибаюсь, в студии можно даже увидеть к каким данным.
                Доброй ночи, спасибо всем кто откликнулся.

                IResponse - реализовывал не я, исходников нет, черный ящик. 3 метода найдены в имеющихся исходниках.
                Да, этот модуль (до переписывания) вызывал вылеты, но я думал что это из-за создания сотни потоков там где это даром не надо.

                В лог данные действительно пишутся, но моим модулем (вывод в лог чуть ли не в каждой процедуре) и в другой лог еще одним модулем т.к. я включил в нем максимальный дебаг. Тот модуль, который содержит IResponse ничего в логи не пишет.

                GetData(i) выдает i-й элемент массива, на чтение, в него параллельно ничего не пишется (по крайней мере как я это понимаю). ОК, пару критических секций там не помешает, посмотрю на что это повлияет кроме производительности.
                  Цитата Виталь @
                  посмотрю на что это повлияет кроме производительности
                  И мне так же интересен результат. :)
                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                  0 пользователей:


                  Рейтинг@Mail.ru
                  [ Script execution time: 0,0362 ]   [ 17 queries used ]   [ Generated: 28.03.24, 17:43 GMT ]