Ass Violation

Ass Violation



🛑 👉🏻👉🏻👉🏻 INFORMATION AVAILABLE CLICK HERE👈🏻👈🏻👈🏻

































Рано или поздно каждый пользователь оказывается в ситуации, когда программа "слетает". Уверен, что это знакомо всем читателям "Компьютерных вестей". Ситуация, когда приложение после "слетания" выдает сообщение об ошибке типа access violation, является весьма распространенной, а потому имеет смысл поговорить о ней в нашей традиционной рубрике FAQ.
"Access violation" в переводе с английского языка означает "нарушение доступа". Сразу же возникает закономерный вопрос: какой доступ и кто его нарушает? Дело в том, что любая программа использует для своей работы память (речь идет об оперативной памяти, а не о запоминающих устройствах), что вполне логично и закономерно. Памяти на всех не хватает, и в системе она распределяется динамически - когда приложению нужно больше памяти, оно запрашивает её у операционной системы. Если же, напротив, в какой-то момент времени памяти нужно меньше, чем приложению было выделено операционной системой, то оно должно "поделиться" излишками, то есть освободить не нужную ему больше память, которая после этого может быть выделена другим приложениям.
Собственно, именно с динамическим распределением памяти и связаны ошибки нарушения доступа. Дело в том, что довольно часто возникает ситуация, когда приложение "забывает" о том, что оно уже освободило какую-либо область памяти, и пытается прочитать из неё или записать в неё какие-либо данные. Такие действия вызывают вполне закономерный протест со стороны операционной системы, поскольку она знает, что в эту область этому приложению данные писать никак нельзя и считывать из неё тоже. Именно тогда на экране вы видите сообщение об ошибке нарушения доступа. Справедливости ради стоит отметить, что далеко не всегда появление этой ошибки приводит к аварийному завершению работы приложения.
Современные технологии разработки программного обеспечения вполне успешно преодолели данную ошибку. Она решается путем автоматического слежения за состоянием памяти средой выполнения программы - теперь освобождение памяти после её использования ложится не на программиста, создающего программный код, а на среду, в которой программа выполняется (т.н. "сборка мусора"). Впрочем, в силу того, что для некоторых распространенных языков создания приложений для Windows (C/C++, Delphi) такой способ решения проблемы неприменим, все новые и новые приложения продолжают "радовать" нас ошибками "Access violation".
У вас есть вопрос? Присылайте его на dreamdrusch@tut.by, и мы рассмотрим его вместе на страницах "Компьютерных вестей"!
Заметили ошибку? Выделите ее мышкой и нажмите Ctrl+Enter!

...when altering one's mind becomes as easy as programming a computer, what does it mean to be human?..
  for X := 1 to Length(List) do // ошибка! Должно быть: for X := 0 to Length(List) - 1 do
  Stream.ReadBuffer(S1, 256);     // портит указатель S1
  Stream.ReadBuffer(S1[0], 256);  // читает данные из потока в массив
  FillChar(S2, Length(S2), 0);            // портит указатель S2
  FillChar(Pointer(S2)^, Length(S2), 0);  // очищает строку, забивая её данные нулями
  Lib1 := LoadLibrary('MyDll.dll');         // один код загрузил библиотеку. Быть может - другой поток
  Lib2 := GetModuleHandle('MyDll.dll');   
  Proc := GetProcAddress(Lib2, 'MyProc');   // нет проверки на ошибку. Функции может не быть - тогда Proc будет равна nil
  Proc;                                     // Proc может быть равна nil - будет Access Violation
  FreeLibrary(Lib1);                        // ещё какой-то код выгрузил библиотеку
  Proc;                                     // хотя Proc <> nil, код, на который она указывает,
                                            // больше не загружен - здесь будет AV.
  Str.Add('S'); // Ошибка! Мы забыли создать объект вызовом Str := TStringList.Create;
  Str.Free; // Здесь мы удалили объект, но ссылка Str по-прежнему указывает на ту же область памяти
  if Str.Count > 0 then // Ошибка! Обращение к уже удалённому объекту
procedure TForm13.Button1Click(Sender: TObject);
  I := 2;           // предположим, что это значение как-то вычисляется и
                    // из-за ошибки в программе получает неверное значение
  S[I] := 0;        // эта строка затрёт адрес возврата из Button1Click в стеке
end;                // в этой строке произойдёт Access Violation, т.к. мы испортили адрес возврата
procedure TForm13.Button2Click(Sender: TObject);
  I := -6;          // пусть мы снова ошиблись в I
    S[I]     := 1;  // вместо массива мы стираем обработчик исключений, установленный try
    Abort;          // полный вылет программы, т.к. менеджер исключений обнаружил испорченный стек
procedure TForm13.Button3Click(Sender: TObject);
  I := -1;          // пусть мы снова ошиблись в I
  S[I] := 1;        // хотя мы снова портим стек, но нам это сходит с рук
                    // никакого EAccessViolation не будет вовсе!
Отличная статья! только мелкие опечатки ,s поправить)
как то: Ищем причину... п.6, коментарий к коду "нет про_ерки на ошибку..."
и т.п.
Да, спасибо за замечания. Пробежался по тексту - вроде ещё 2 опечатки нашёл.
В браузере, в котором писал, не была доступна проверка, ну а глаза видят только то, что хочет видеть мозг.
Спасибо за информацию. Доступно!.

Было бы здорово, если бы ты описал ещё так же доступно про утечки памяти (memory leaks). В разрабатываемом проекте они часто приключаются, а хорошего описания (что и к чему) не нашёл (возможно плохо искал).

Буду ждать ;)
>>> Было бы здорово, если бы ты описал ещё так же доступно про утечки памяти (memory leaks)
Я как раз готовлю такой материал. А вообще это было ещё вот здесь (во второй части).
скажите, а если два потока одновременно читают тот же участок памяти, Access Violation не случитсо?
Если память доступна - то никаких проблем.

Только убедитесь, что вы не используете эти данные для синхронизации и что у вас нет чередования запись/чтение.
Если есть сомнения - используйте критическую секцию.

P.S. По потокам вообще в Delphi можно почитать вот это.
вспомнилось, из фильма вроде:
"пить, курить и всовывать он начал одноврёмённо..."
:)
Спасибо за статью! )
Я пишу сервер на Делфи7, и тут такая есть бяка с менеджером памяти после 2-5 дней работы сервера: (Допустим речь идет о вызове функции которая должна возвращать объект класса).Менеджер иногда не обнуляет нормально указатель на объект в самом начале, и указатель имеет вид что-то типа ($0000010), и соответственно код
If Assigned(Класс) then
Класс.Create
просто пропускается так как Assigned($00000010) = True;
Ну потом отсос виалейшен фискульт привет при любом обращении к объекту....
Или это Делфи7 такой глючный или помогите советом!
(борюсь - везде сначала обнуляю указатели) но это не всегда уследить можно..
Спасибо!
опечатался в коде в предыдущем комменте, тут правильно
If NOT Assigned(Класс) then
Класс.Create
Yaroslav, можно прикрутить костыль к вашему коду)))
if (integer(Класс)<100) then
Класс := Класс.Create;
Есть еще один случай получения AV, очень неприятный.
Признаки: программа работала нормально, развивалась, но некоторое время назад стали появляться AV, причем в неожиданных местах. Какой билд дал такой эффект установить крайне трудно. Под отладчиком AV не появляется.
Краткое описание: программа однопоточная, dll не используется, активная работа с формами, в том числе модальными и вспомогательными плавающими, StayOnTop. Формы создаются динамически, dll и пакетов не употребляется, кое-где используется СОМ, как с ранним, так и с поздним связыванием. Везде используется FreeAndNil.
Пользователи клянутся, что не могут найти последовательность действий, приводящую к AV.
А о себе написал что техно-гик)))
хотя и верно...
Но наверняка ошибка вызывается сломанным блоком RAM,так что и ее нужно проверить.
спасибо за статью, очень познавательно. вот только так и не могу понять, почему "идёт обращение по ссылке равной nil" в деструкторе формы...
У меня access violation at ardress 00000000. read of ardress 00000000 вылетает при попытке создать новый проект. у меня стоит delphi 2010.
Наверное надо отличать проблемы ваших приложений от проблем среды Delphi?

Эта статья говорит о решении проблем в ваших программах.

Для решения проблем с самой Delphi - идите куда-нибудь ещё. Предпочтительно - в тех-поддержку Embarcadero (я искренне не понимаю людей, спрашивающих подобные вопросы где угодно, но только не у разработчиков Delphi - кому как не им знать, что может быть не так с их программой?).
А не подскажете тогда ссылочку на страницу техподдержки, где можно задать такой вопрос?
Ээээ.... ну вы даёте.

Официальный сайт, в меню выбираем Services/Customer Support - переходит на сайт суппорта - там есть большая кнопка "Create case".

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

Альтернативно, можно попробовать писать на адрес российского представительства (нашёл в разделе контакты).
Уважаемый Александр! Вы как профессионал в этом деле наверно сможете мне помочь! Вот тут я описала вкратце мою проблему: http://www.adminplanet.ru/t4789.html#post15703
Если вы знаете как её решить, напишите мне, пожалуйста, на moorlena@mail.com
Возможно я тоже буду вам чем-то полезна.
у меня тоже access violation at address 00000000. read of address 00000000 я почитал разделы,но толком так и не понял где искать,и ещё,дэлфи обязательна? у меня ошибка выходит когда в онлайн игру захожу.пожалуйста подскажи.
Неужели сложно сообразить, что эта статья написана для программистов (разработчиков программ)? Вы программист? Вы писали эту онлайн-игру? Нет? Вот и топайте отсюда.
Здравствуйте, Александр! У меня проект компилируется без ошибок, всё чётко. Экзешник работает без проблем, а когда запускаю его на другом компе, сразу вылетают 2 ошибки: Access Violation at address 005560E1 in Module MyProg.exe Read of address 0 и No MCI Device Open, хотя запускается. Но это не красиво. Подскажите, что сделать? Заранее благодарю.
Есть два варианта.

Вариант первый - гадать. Например, из сообщения "No MCI Device Open" видно, что ваша программа как-то работает с мультимедийными функциями (по идее, это вы нам должны говорить, а не мы угадывать). Ещё это сообщение говорит, что ваша программа пытается что-то сделать, не открыв (инициализировав) устройство. Откуда можно получить гипотезу: вы открываете устройство, но не проверяете возвращаемое значение. Функция же на второй машине по какой-то причине завершается с ошибкой, возвращая nil (что подтверждается "Read of address 0"). Поскольку вы не анализируете результат вызова, а вслепую продолжаете работать дальше, то вы получаете свой законный щелчок по лбу (Access Violation).

Что делать: писать нормальный код, обрабатывая ошибки вызова функций. Предпочтительно писать самостоятельно, а не тупо копировать уже написанный код (обработку ошибок в котором никто делать не удосуживался).

Вариант второй - не гадать, а использовать инструменты.

Инструмент номер 1 - локальный отладчик. Запустите программу, нажмите Run/Pause, а затем - Search/Go to address, введите $5560E1, нажмите OK. Отладчик переместит вас в точности то место, где возникла проблема (разумеется при условии, что у себя вы запустили в точности тот вариант программы, который запускали на другой машине). Смотрите, куда вас ткнул отладчик, анализируйте код в этой строке.

Инструмент номер 2 - удалённый отладчик. На ту машину, где происходит AV ставите клиента отладчик (как это делать - написано в справке Delphi или интернете), подключаетесь к той машине со своей (где у вас Delphi стоит), запускаете программу, там возникает AV, а отладчик это видит и сигнализирует обычным образом - всё, останавливаетесь, исследуете, смотрите текущее место, стек вызовов, значения переменных - всё как обычно.

Инструмент номер 3 - трейсер исключений. EurekaLog, madExcept или JclHookExcept.pas из JCL - это основные варианты. Подключаете к программе, переносите программу на ту проблемную машину, запускаете, получаете AV - трейсер исключений сгенерирует вам отчёт. Изучаете отчёт, находите проблему.
Спасибо за подсказки, получилось! Отпишусь: все заработало с помощью обычного try..except :)
Вот в конкретном месте:
try
CoCreateInstance(CLSID_VCmd, nil, CLSCTX_ALL, IID_IVoiceCmd, fIVoiceCmd);
fIVoiceCmd.QueryInterface(IID_IVCmdAttributes, fIVCmdAttrs);
OleCheck(fIVoiceCmd.Register(nil, TVCmdNotifySink.Create(Self),
IVCmdNotifySink, VCMDRF_ALLMESSAGES, nil));
CreateCommandMenu;
fIVCmdAttrs.EnabledGet(Enabled);
fIVCmdAttrs.AwakeStateGet(Awake);
except
ShowMessage('Cannot do it my darling!');
end;
Неправильно.

У вас в коде отсутствует обработка ошибок. CoCreateInstance и QueryInterface - функции. Они возвращают значение, которое вы игнорируете, а должны были бы анализировать.

Например так:

OleCheck(CoCreateInstance(CLSID_VCmd, nil, CLSCTX_ALL, IID_IVoiceCmd, fIVoiceCmd));
OleCheck(fIVoiceCmd.QueryInterface(IID_IVCmdAttributes, fIVCmdAttrs));
OleCheck(fIVoiceCmd.Register(nil, TVCmdNotifySink.Create(Self),
IVCmdNotifySink, VCMDRF_ALLMESSAGES, nil));
...

При необходимости - завернуть в:

try
...
except
on E: EOleError do
ShowMessage('Sorry, error: ' + E.Message);
end;

Ну или хотя бы как-то так:

CoCreateInstance(CLSID_VCmd, nil, CLSCTX_ALL, IID_IVoiceCmd, fIVoiceCmd);
if not Assigned(fIVoiceCmd) then
Exit;
fIVoiceCmd.QueryInterface(IID_IVCmdAttributes, fIVCmdAttrs);
if not Assigned(fIVCmdAttrs) then
Exit;
OleCheck(fIVoiceCmd.Register(nil, TVCmdNotifySink.Create(Self),
IVCmdNotifySink, VCMDRF_ALLMESSAGES, nil));
...
Уважаемый автор! Респект тебе и уважуха! Без тебя накрылась бы дипломная, а так, вычеслил ошибки и пофиксил, Спасибо!
Здравствуйте! Спасибо автору статья хороша! Хотел бы заметить что у меня вылетала AV только потому что я вместо Объект:=Тип_Объекта.create; писал Объект.create; хотя казалось бы ;)
Огромное вам спасибо! С помощью самого начала вашей статьи за минуту нашёл ошибку, которую не мог найти 3 часа (не приходилось раньше пользоваться отладчиком)!
В очередной раз убедился - всегда виноват сам.
что делать если access violation at address in module rtl60.bpl вылезает при закрытии программы и даже при просто закрытии делфи.
Добрый день! У меня возникла проблема с WebServices
Итак...сделан клиент и сервер...с помощью C++ Builder на Windows 7
Клиент работает отлично на Windows 7, XP, Windows Server 2003, а вот на Windows Server 2008 R2 пишет ошибку access violation at address....(при этом на сервере в логах вообще ничего нет...то есть он просто не может дать запрос на сервер)
Помогите советом как решить эту проблему...пожалуйста
в моем случае , без открывания или закрывания программ , само произвольно вылезает примерно 70 окон с ошибкой :
access violation at address 037b84db Read of address 00000180
Что делать в моем случае ?

у меня такая проблема, написал програмку у меня все работает и у многих других тоже, а у некоторых вылазит AV, с чем это может быть связано?
Это риторический вопрос? Любой Access Violation обусловлен багом в коде. В 99% случае - в вашем коде.

Или вы не понимаете, как такое может быть что иногда работает, а иногда - нет? Ну вот есть пример в п. 7 к разделу "Ищем причину возникновения Access Violation анализом кода".

Или вы не знаете, как искать причину? Ну вот же целая статья. А для сторонней машины даже и комментарий.
Здравствуйте, хорошая статья. Вот только возник вопрос. Я не пишу сам код, я лишь эксплуатирую поставленное для нашей компании ПО, т.е. доступа к кодам у меня нет.
ПО работало на протяжении 5-6ти лет без проблем, пока не вышла из строя материнская плата ПК. Заменили плату на аналогичную, все драйвера подхватились, кроме звука (установили вручную отдельно), ну и установили новый антивирус macafe. В итоге при запуске ПО (программа взвешивания ж/д транспорта) появляется ошибка "Acsess violation at adress 004A3C58 in module "WinVesy.exe" read of adress 00000034" можно ли устранить проблему не без исходников ПО?? Теоретически может ли ПО конфликтовать с антивирусом? ПО ошибку выдаёт не всегда, например если перезагрузить копм и сразу запустить ПО оно запускается.

> можно ли устранить проблему без исходников ПО?

Нельзя.

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

А если смотреть на это шире: где гарантии, что программа работает правильно? Если в ней есть одна ошибка (обращение к неинициализированной памяти), то почему бы не быть и другой?
Александр, можете посоветовать способ (в академических целях) гарантированно получить AV без обращения по nil?
Я полагаю, это вот например не гарантия вылета?

procedure P(Sender: TObject);
var
S: array [0..0] of Integer;
I: Integer;
begin
I := 1;
S[I] := 0;
end;

или

procedure P2;
var
S: array [0..0] of Integer;
I: Integer;
begin
I := -6;
try
S[I] := 1;
Abort;
except
end;
end;
Вопрос не понятен, поскольку nil ничем не отличается от любого другого адреса.

Например: P := Pointer(1); I := PInteger(P)^; - даст A/V, поскольку $00000001 < 4 Кб, и, следовательно, принадлежит защитной странице памяти, в которую входит и nil.

Другой пример - P := VirtualAlloc(..., MEM_RESERVE); I := PInteger(P)^; - даст A/V, т.к. просходит обращение к зарезервированному, но не выделенному участку памяти.

Третий пример: P := VirtualAlloc(...); VirtiulFree(P); PInteger(P)^; - даст A/V, т.к. просходит обращение к не выделенной памяти. Правда, при условии, что в программе - 1 поток (что вы, в общем случае, гарантировать не можете).
Я имел в виду следующее: nil гарантировано указывает "в никуда" и обращение недопустимо. В остальных случаях при обращении по адресу может как возникнуть AV (если скажем память защищена или не выделена) так и нет (нам не повезло и мусорный указатель чисто случайно указал на доступный нам кусок памяти).

Ещё раз повторюсь, вопрос чисто был академический. Вопрос родился из желания привести студентам пример кода иллюстрирующий полезность FreeAndNil. В принципе, Я ответ получил. Спасибо.
Да, гарантировано вы получите A/V только при попадании в первые 64 Кб (зона отлова нулевых указателей) и в 64 Кб на границе 2 Гб. В остальном - как повезёт.
Александр, здравствуйте.
Пишу программу на Delphi 7. Испрользую BDE, EhLib 6.2.
В программе на главной форме есть TPageControl в нем два TabSheet'a, на первом находится DBgridEh1 в котором отражаются отфильтрованные записи из BDEMainTable, на втором TabSheet'e находится DBGridEh2 через который я вношу изменения в BDEMainTable, если я вношу изменения через DBGridEh2, перехожу на TabSheet1 потом снова возвращаюсь на TabSheet2, снова вношу изменения, снова перехожу на TabSheet1, перехожу на TabSheet2 и при нажатии на поле для изменения значения вылетает Access Violation at address 00456D60 in module 'My.exe'.Read of address 00000031. Помогите, пожалуйста разобраться, в чем может быть проблема?

Что вы ожидаете услышать в ответ? "У вас ошибка в строке 152"?

Я же не вижу ваш код, у меня нет доступа к адресам памяти в вашем приложении. Это вы должны нам рассказывать, почему у вас возникает ошибка, а не мы вам.

А делать вы это должны - исследуя ситуацию с помощью инструментов. Как? А вот как написано в этой статье.

Например, читаем раздел "Ищем причину возникновения Access Violation анализом данных", смотрим на "Read of address 00000031". Уже отсюда я могу заключить, что у вас произошла попытка прочитать поле объекта, ссылка на который = nil (т.е. объект уже удалён или не создан). Причём, объект относительно сложный, т.к. смещение 31 - достаточно велико (у простых/небольших объектов это будет 4, 8, 12...).

Далее, "at address 00456D60" сообщает вам точное место, где произошла ошибка. Я не телепат, я не знаю, что у вас за код находится по этому адресу. А вот вы можете как использовать Search / Go To Address, так и просто отладчик - при исключении он остановит вас именно на этом месте. В любом случае вы посмотрите на строчку кода, проверите значения переменных в ней и увидите, кто из переменных, к которым обращается строчка
Ошибка STATUS ACCESS VIOLATION — универсальные...
Что такое access violation? | KV.by
Блог GunSmoker-а: Access Violation в деталях
Ошибка Access violation at address … in module
Ошибка Access violation at address и способы решения
70 Year Old Pussy
Oldman69
Escort At Hotel
Ass Violation

Report Page