Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.11.28;
Скачать: [xml.tar.bz2];

Вниз

Как бороться с Access violation?   Найти похожие ветки 

 
cvg   (2004-11-11 10:49) [0]

Hi All! Subj. Прога иногда затыкакется, выкидывая сообщения такого вот типа: "Project abc.exe raised exception class EAccessViolation with message "Access violation at address 00401C7A in module "abc.exe". Process stopped. Use stop or Run to continue." И как же с этим делом бороться?


 
Семен Сорокин ©   (2004-11-11 10:51) [1]

Веревку с мылом, конечно же, не предлагать? :)


 
ЮЮ ©   (2004-11-11 10:54) [2]

Use Run to continue - и смотри что, где и по чём :)


 
cvg   (2004-11-11 10:58) [3]

Не. Вот без мыла -- еще туда-сюда. Насколько я понимаю, там какие-то стуртуры экзюшника пытаются получить доступ к месту в экзюшнике, уже заблокированному другими структурами?


 
Ddd-01   (2004-11-11 10:59) [4]

Нужно зармеить код из-за которого это происходит


 
Amoeba ©   (2004-11-11 11:00) [5]


> И как же с этим делом бороться?

Исключительно путем исправления грубых ошибок в коде!


 
Семен Сорокин ©   (2004-11-11 11:00) [6]


> Насколько я понимаю, там какие-то стуртуры экзюшника пытаются
> получить доступ к месту в экзюшнике, уже заблокированному
> другими структурами?

Совсем сложный случай, но вот пошаговую отладку еще никто не отменял.


 
cvg   (2004-11-11 11:01) [7]

В файле GETMEM.INC останавливается на второй строчке из нижеприведенных:

   p := f.prev;
   n.prev := p;
   p.next := n;


 
ЮЮ ©   (2004-11-11 11:01) [8]

Нет, просто автор кода полагает, что обращается именно к тем данным, о которых он думает, а на самом деле всё далеко не так


 
Amoeba ©   (2004-11-11 11:01) [9]


> Ddd-01   (11.11.04 10:59) [4]
> Нужно зармеить код из-за которого это происходит

Ошибки надо исправлять, а не заремливать.


 
Amoeba ©   (2004-11-11 11:04) [10]


> cvg   (11.11.04 11:01) [7]
> В файле GETMEM.INC останавливается на второй строчке из
> нижеприведенных:
>
>    p := f.prev;
>    n.prev := p;
>    p.next := n;

Ну и что с того? Телепатов и мастеров гадания на кофейной гуще здесь нет. Просим в студию КОД, а не его абсолютоно неинформативный огрызок.


 
cvg   (2004-11-11 11:04) [11]

Вот процедура целиком, где это происходит (насколько я понимаю, стандартная, потому что основу проги писал не я):

procedure DeleteFree(f: PFree);
var
 n, p: PFree;
 size: Integer;
begin
 if rover = f then
   rover := f.next;
 n := f.next;
 size := f.size;
 if size <= cSmallSize then begin
   if n = f then
     smallTab[size div cAlign] := nil
   else begin
     smallTab[size div cAlign] := n;
     p := f.prev;
     n.prev := p;
     p.next := n;
   end;
 end else begin
   p := f.prev;
   n.prev := p;
   p.next := n;
 end;
end;


 
Amoeba ©   (2004-11-11 11:07) [12]

A где описание типа PFree и глобальных переменных? Опять заставляешь гадать?


 
cvg   (2004-11-11 11:11) [13]


type
 PFree = ^TFree;
 TFree = packed record
   prev: PFree;
   next: PFree;
   size: Integer;
 end;
 PUsed = ^TUsed;
 TUsed = packed record
   sizeFlags: Integer;
 end;


 
Плохиш ©   (2004-11-11 11:13) [14]

f.next = nil!


 
ЮЮ ©   (2004-11-11 11:14) [15]

n := f.next;
если f.next = nil, то и n будет nil, поэтому на строке
n.prev := p
AV просто обязано быть


 
Amoeba ©   (2004-11-11 11:15) [16]

А теперь, пожалуйста, еще и описание переменной smallTab в студию.


 
cvg   (2004-11-11 11:17) [17]


type
 TSmallTab    = array [sizeof(TFree) div cAlign .. cSmallSize div cAlign] of PFree;


 
Плохиш ©   (2004-11-11 11:18) [18]

>Amoeba ©   (11.11.04 11:15) [16]

Интелектуальную собственность воруем? ;-)


 
cvg   (2004-11-11 11:19) [19]


const
 cAlign        = 4;
 cThisUsedFlag = 2;
 cPrevFreeFlag = 1;
 cFillerFlag   = Integer($80000000);
 cFlags        = cThisUsedFlag or cPrevFreeFlag or cFillerFlag;
 cSmallSize    = 4*1024;
 cDecommitMin  = 15*1024;


 
TUser ©   (2004-11-11 11:21) [20]

Мне уже интересно - как GetMem.inc дебажить?


 
cvg   (2004-11-11 11:21) [21]

Плохишу: Заголовок у этого модуля:


{ *********************************************************************** }
{                                                                         }
{ Delphi Runtime Library                                                  }
{                                                                         }
{ Copyright (c) 1996,2001 Borland Software Corporation                    }
{                                                                         }
{ *********************************************************************** }


 
Amoeba ©   (2004-11-11 11:36) [22]


> cvg   (11.11.04 11:21) [21]

В таком случае ищи ошибку не у Borland"а, а в своем собственном коде.


 
cvg   (2004-11-11 11:39) [23]

Ну дак в том и вопрос: в котором именно (или хотя бы примерно) месте ее искать?


 
Amoeba ©   (2004-11-11 11:48) [24]


> cvg   (11.11.04 11:39) [23]
> Ну дак в том и вопрос: в котором именно (или хотя бы примерно)
> месте ее искать?

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


 
Digitman ©   (2004-11-11 11:57) [25]


> cvg   (11.11.04 11:39) [23]



> выкидывая сообщения такого вот типа: "Project abc.exe raised
> exception class EAccessViolation with message "Access violation
> at address 00401C7A in module "abc.exe"


вот эта самое "00401C7A" и "abc.exe" - это не для Пушкина, это для тебя  инф-ция !

это - фрагмент Справки :

Choose Search|Find Error to display the Find Error dialog box.

Find Error dialog box

Use this dialog box to specify the address of the most recent runtime error.

Error Address
The address of the most recent runtime error and the error number appears in the runtime error report if it is available.

When you click OK, Delphi recompiles your program and stops at the address location you entered, highlighting the line that caused the runtime error.

the address - та самая галиматья "00401C7A"


 
cvg   (2004-11-11 12:06) [26]

Ну так вот она и остановилась на сторочке

 n.prev := p;

И что мне с ней делать?


 
Семен Сорокин ©   (2004-11-11 12:18) [27]


> cvg   (11.11.04 12:06) [26]
> Ну так вот она и остановилась на сторочке
>
>  n.prev := p;
>
> И что мне с ней делать?

А про Call Stack Вы слышали?


 
REA   (2004-11-11 12:19) [28]

В "экзюшнике" все дело...


 
TUser ©   (2004-11-11 12:21) [29]


> в котором именно (или хотя бы примерно) месте ее искать?

Уж точно не в ГетМем


 
Плохиш ©   (2004-11-11 12:23) [30]


>cvg   (11.11.04 11:21) [21]
>Плохишу: Заголовок у этого модуля:

А вот незачем лезть в менеджер памяти борланда, не понимая что делаешь и как это работает.


 
Romkin ©   (2004-11-11 12:24) [31]

Двунаправленный список :)) С ним оченно осторожно надо работать, смотреть, чтобы все указатели шли как надо.
Плюс AV - очень неприятная вещь, скорее всего ошибка не здесь, а в другом месте: где-то путает ссылки. И происходит обращение в то место памяти, которая уже освобождена. Это называется висящей ссылкой, очень неприятно: ссылалось поле на запись, потом ее освободили, а ссылку не скорректировали...
Решение: отлаживать, смотреть исходники, доказывать правильность каждой процедуры и тд.


 
Digitman ©   (2004-11-11 12:25) [32]


> cvg   (11.11.04 12:06) [26]
> Ну так вот она и остановилась на сторочке
>
>  n.prev := p;
>
> И что мне с ней делать?


вариантов не так уж и много, всего-то два:

1. Выкинуть нкафих свою программу в мусор, забросить навсегда это гиблое дело и заняться чем-нть иным, не менее полезным. но более простым.

2. Оттрассировать программу и понять, почему значение переменной n в момент выполнения упомянутой строчки равна черт-те чему, но только не тому что ожидалось тобой.


 
cvg   (2004-11-11 13:49) [33]

А это вот из той же серии? (остановилась на строке "Error(reInvalidPtr);"):

function _FreeMem(P: Pointer): Integer;
{$IF Defined(DEBUG) and Defined(LINUX)}
var
 Signature: PLongInt;
{$IFEND}
begin
 if P <> nil then
 begin
{$IF Defined(DEBUG) and Defined(LINUX)}
   Signature := PLongInt(LongInt(P) - 4);
   if Signature^ <> 0 then
     Error(reInvalidPtr);
   Signature^ := FreeMemorySignature;
   Result := MemoryManager.Freemem(Pointer(Signature));
{$ELSE}
   Result := MemoryManager.FreeMem(P);
{$IFEND}
   if Result <> 0 then
     Error(reInvalidPtr);
 end
 else
   Result := 0;
end;


 
Digitman ©   (2004-11-11 13:55) [34]


> cvg   (11.11.04 13:49) [33]


похоже, что из той же...

только вот в данном простейшем случае нет никакого повода лезть так глубоко - в дебри System.pas

если следы ведут к строчке

n.prev := p

то совершенно очевидно, что блох следует искать у себя, а не у Борланда

ищи место в СВОЕМ алгоритме , где у тебя переменная n в какой-то момент времени по ходу работы ТВОЕГО алгоритма приобретает черт-те какое значение, только не то что ты ожидаешь иметь в этой строчке


 
Rem ©   (2004-11-11 14:28) [35]

Если код - не Ваш, то начните с анализа алгоритма.
Потом проанализируйте работу алгоритма в частных случаях:
- начала списка;
- конца списка;
- в случае пустого списка.
Хорошо проработанный алгоритм легко обходит подобные ситуации.

Как крайний случай, прежде чем использовать элемент, проверяйте его на неравенство nil:
if (n <> nil) then
 ...


Однако, это не лучший выход, так как автором алгоритма, вероятно, не были проработаны все детали, и, в следствие этого, у Вас может появится "странное" поведение программы.


 
cvg   (2004-11-11 15:21) [36]

To Digitman: ну, попробовал я поставить на этой точке останов. Но ведь 1) эта функция офигеть сколько раз вызывается; 2) ну, равно там это p какому-то числу, но оно же же мне ни о чем не говорит абсолютно.

А вот при обработке прогой одного из файлов она выдала ту же ошибку, но только в ней написано "Write of address 00000000". Куда это она собирается по нулевому адресу чего-то записать?


 
Romkin ©   (2004-11-11 15:23) [37]

0 - это nil :)) То есть, уже прогресс: ссылка была обнулена, а ты к ней обратился.


 
cvg   (2004-11-11 15:38) [38]

Как правильно написать? --

f p = $00000000
then n := 0;
     n.prev := p;
     p.next := n;


 
Digitman ©   (2004-11-11 15:48) [39]


> 1) эта функция офигеть сколько раз вызывается


и что ?


> 2) ну, равно там это p какому-то числу, но оно же же мне
> ни о чем не говорит абсолютно


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

третьего не дано.


 
Rem ©   (2004-11-11 16:05) [40]

cvg   (11.11.04 15:38) [38]
n := 0;
n.prev := p;


После такого перла я почти согласен с

"переквалифицируйся в кого угодно, хоть управдомы, ибо программингом заниматься - явно не твое дело"

То-то у нас проблемы с коммунальными услугами! Потому что у нас такие управдомы!



Страницы: 1 2 вся ветка

Форум: "Основная";
Текущий архив: 2004.11.28;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.55 MB
Время: 0.036 c
1-1100667952
Maxim2030
2004-11-17 08:05
2004.11.28
стандарты кодирования на Delphi


6-1095357819
Роман
2004-09-16 22:03
2004.11.28
Как запретить отключение графики в WB?


1-1100511356
Yorik
2004-11-15 12:35
2004.11.28
Как проверить только ли латинские символы в переменной?


11-1082825813
Max003
2004-04-24 20:56
2004.11.28
Что делать? Минимальный MCK проект(пустая форма) весит 25.5 кб


14-1100095253
race1
2004-11-10 17:00
2004.11.28
component needed





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский