Форум: "Прочее";
Текущий архив: 2007.06.03;
Скачать: [xml.tar.bz2];
ВнизПодскажите софтину Найти похожие ветки
← →
Ega23 © (2007-05-08 11:06) [0]1. В приложении где-то подсчёт ссылок на интерфейсы нарушен. Где - непонятно. Есть ли какой-нибудь хитрый софт, который позволяет это дело как-то отслеживать?
2. Есть ли какая-нибудь софтина, позволяющая сказать, что у меня находится по такому-то адресу памяти? (объект, каким процессом занята и т.п.)
← →
Rouse_ © (2007-05-08 11:10) [1]VTune смотрел?
← →
Игорь Шевченко © (2007-05-08 11:14) [2]
> 2. Есть ли какая-нибудь софтина, позволяющая сказать, что
> у меня находится по такому-то адресу памяти? (объект, каким
> процессом занята и т.п.)
Отладчик
← →
db2admin (2007-05-08 11:15) [3]Ega23 © (08.05.07 11:06)
если Java то весь JMX на это заточен
← →
Ega23 © (2007-05-08 11:21) [4]
> Игорь Шевченко © (08.05.07 11:14) [2]
>
> Отладчик
Да я с ним уже третий день воюю.
Project ARM.exe raised too many consecutive exceptions: "access violation at 0xcc342d24: read of address 0xcc342d24". Process stopped.
фишка в том, что данные адреса всегда постоянные. А из пространства адресов в загруженных модулях, вроде как в 0xcc ни один не попадает...
← →
Ega23 © (2007-05-08 11:22) [5]
> VTune смотрел?
Что за зверь?
← →
Игорь Шевченко © (2007-05-08 11:23) [6]Ega23 © (08.05.07 11:21) [4]
Это ты в данные полез, скорее всего. Но: у тебя есть точка ошибки, у тебя есть call stack - чего еще не хватает для определения источника ошибки ?
← →
Ega23 © (2007-05-08 11:25) [7]Да, вот ещё что.
Данный exception (из [4]) появляется на завершении программы. При этом вываливается CPU-window с окошком exception. Если после закрытия сообщения нажать F9, то секунды через 3-5 оно снова возникает. Если войти в трассировку по F7, то проваливаюсь в дебри ntdll и всё зависает, пока Ctrl+f2 не сделаешь.
← →
DVM © (2007-05-08 11:31) [8]
> Ega23 © (08.05.07 11:25) [7]
А если запускать не из под отладчика что происходит?
← →
ЮЮ © (2007-05-08 11:33) [9]> то проваливаюсь в дебри ntdll и всё зависает
call stack разве не нить Ариадны, которая должна вывести в VCL и твой код? :)
> Данный exception (из [4]) появляется на завершении программы.
"Выполняется код" уже убитого объекта - неостановленного таймера, RxDBFilter-а и прочего, прочего, прочего
← →
Ega23 © (2007-05-08 11:33) [10]
> Это ты в данные полез, скорее всего. Но: у тебя есть точка
> ошибки, у тебя есть call stack - чего еще не хватает для
> определения источника ошибки ?
>
Call stack пуст. Данная ошибка возникает уже после
program ARM;
uses
Forms,
.......
{$R *.RES}
begin
Application.Initialize;
Application.CreateForm(TMainForm, MainForm);
Application.Run;
end.
Встаёшь на end., начинаешь дальше по F7 идти. Отрабатывает несколько секций finalzation, после чего вываливается вот такой вот exception.
← →
Ega23 © (2007-05-08 11:36) [11]
> "Выполняется код" уже убитого объекта - неостановленного
> таймера
Возможно. Действительно, есть там один таймер. Сейчас проверю.
Но всё равно: почему тогда не вызывается вполне конкретный AV на попытку выполнить код убитого таймера?
← →
Rouse_ © (2007-05-08 11:37) [12]
> Что за зверь?
http://www.intel.com/software/products/
← →
Ega23 © (2007-05-08 11:38) [13]
> Rouse_ © (08.05.07 11:37) [12]
Спасибо, сейчас посмотрю.
← →
Romkin © (2007-05-08 11:38) [14]Что, интерфейсы с подсчетом ссылок объединил с прямыми обращениями к объектам? Тогда сочувствую. Ничем здесь не поможешь.
← →
Ega23 © (2007-05-08 11:39) [15]
> А если запускать не из под отладчика что происходит?
Процесс убивается. Вроде как до конца.
← →
Ega23 © (2007-05-08 11:39) [16]
> Что, интерфейсы с подсчетом ссылок объединил с прямыми обращениями
> к объектам? Тогда сочувствую. Ничем здесь не поможешь.
>
Да я тут ничего не объеденял. Код не мой... :)
← →
Ega23 © (2007-05-08 11:41) [17]
> Что, интерфейсы с подсчетом ссылок объединил с прямыми обращениями
> к объектам? Тогда сочувствую. Ничем здесь не поможешь.
>
Просто вижу, что деструкторы у нескольких InterfacedObject"ов не отрабатывают. Есдинственное объяснение - где-то ссылки остались.
← →
Lamer@fools.ua © (2007-05-08 11:44) [18]
[OFFTOPIC]
>Код не мой...
... я просто разместил объяву... :-)[/OFFTOPIC]
← →
Romkin © (2007-05-08 11:51) [19]Ega23 © (08.05.07 11:41) [17] А, ну тогда еще ничего :) А из release вызов есть? Уверен, что _release не перекрыли?
Логируй addref и release. Это самое простое и действенное :)
← →
Romkin © (2007-05-08 11:58) [20]Сделал ли следующее:
1. Проверить методы _AddRef и _Release всех потомков, на предмет отключения подсчета ссылок
2. Поиском найти места вызовов этих методов, и посмотреть, какого фига :)
3. Поиском найти pointer( и посмотреть, а не преобразуют ли интерфейсы
4. Обратные вызовы есть? Тогда еще их подключение посмотреть. В частности, InterfaceConnect вызовы есть? Оно тоже AddRef делает.
← →
Ega23 © (2007-05-08 11:59) [21]
> Ega23 © (08.05.07 11:41) [17] А, ну тогда еще ничего :
> ) А из release вызов есть? Уверен, что _release не перекрыли?
>
> Логируй addref и release. Это самое простое и действенное
> :)
там в модуле вот такой вот хитрый код есть:
initialization
app := TARMApplication.Create;
(app as IUnknown)._addRef;
где TARMApplication = class(TInterfacedObject,IARMApplication,IBlockableMessageSink,IMessageProvider)
нафига он там такой - мне не совсем понятно.
← →
Romkin © (2007-05-08 11:59) [22]5. Проверить, а нет ли где запоминания объекта, а не его интерфейса, и при этом есть подсчет ссылок - переписать нормально.
← →
Romkin © (2007-05-08 12:02) [23]Ega23 © (08.05.07 11:59) [21] Упс. а app типа запоминается и к нему обращения есть? И TARMApplication _Release не перекрыт?
Если да - убей об стену разработчика с его хитростями :)
Ох, я правильно понимаю, "Sink" - там еще и события?! Млин.
← →
Romkin © (2007-05-08 12:07) [24]Дело в том, что когда кто-то подсоединяется к событиям, то у этого кого-то вызывается addref. И если этот кто-то держит у себя источник событий (тоже вызвал addref у него), то легко получить дедлок: два интерфейса держат дрг друга, намереваясь отвязаться на destroy, который вызовется, когда refcout дойдет до нуля... :)))
← →
Ega23 © (2007-05-08 12:18) [25]
> Упс. а app типа запоминается и к нему обращения есть?
А app - это прямо в этом же модуле var app : TARMApplication; И обращения - таки есть... :(
А что касается [24] - скорее всего именно так и происходит...
← →
oxffff © (2007-05-08 12:53) [26]
> там в модуле вот такой вот хитрый код есть:
>
> initialization
> app := TARMApplication.Create;
> (app as IUnknown)._addRef;
>
>
В данном коде _addRef будет вызван два раза +
будет создана глобальная временная переменная, которая будет неявно финализирована( вызов _Release) по завершению приложения.
← →
oxffff © (2007-05-08 12:56) [27]Покажи секцию finalization или место где и как разрушается app.
← →
Romkin © (2007-05-08 14:22) [28]oxffff © (08.05.07 12:53) [26] Нет, тут app: TARMApplication. Вот человек и защелкнул его вызовом addref.
То есть, запоминается ссылка на объект, который контролируется по подсчету ссылок. Плюс у него есть интерфейс событий.
Последствия в этом случае просто непредсказуемые :)
В finaliяation должен быть просто вызов _release, и присвоение переменной nil, если следовать его логике. С надеждой, что все будет в порядке...
Ega23 © (08.05.07 12:18) [25] Ну что я могу посоветовать... Сделай app функцией, возвращающей интерфейс разве что. Интерфейс, который экспонирует все методы TARMApplication, к которым есть обращения из кода.
← →
oxffff © (2007-05-08 15:08) [29]
> oxffff © (08.05.07 12:53) [26] Нет, тут app: TARMApplication.
> Вот человек и защелкнул его вызовом addref.
> То есть, запоминается ссылка на объект, который контролируется
> по подсчету ссылок. Плюс у него есть интерфейс событий.
>
> Последствия в этом случае просто непредсказуемые :)
Что не так?
(app as IUnknown) - уже гарантированно приведет к вызову _Addref
И создаст временную переменную, которая будет жить до "глобальной финализации".
Дополнительный вызов _Addref еще раз приведет к увеличению счетчика.
← →
Romkin © (2007-05-08 15:31) [30]
> (app as IUnknown) - уже гарантированно приведет к вызову
> _Addref И создаст временную переменную, которая будет жить
> до "глобальной финализации".
Ошибаешься. Да, каст к интерфейсу делает AddRef. Потом идет вызов Addref явно, и сразу же неявно вызов Release, временная переменная ушла. Не живет она до финализации :)
Остается явный AddRef.
← →
oxffff © (2007-05-08 16:42) [31]
> Ошибаешься. Да, каст к интерфейсу делает AddRef. Потом идет
> вызов Addref явно, и сразу же неявно вызов Release, временная
> переменная ушла. Не живет она до финализации :)
Отладчик показал, что вы правы.
initialization Scope и finalization Scope разный.
← →
Ega23 © (2007-05-08 16:58) [32]Блин.
Поясните мне, почему в таком вот случае:
unit uMyInterface;
interface
uses SysUtils, Dialogs;
type
IMyInterface = interface
["{2B41F8BB-E80C-453B-98DF-61247935EF6C}"]
procedure DoSomething;
end;
TMyInterfaceObject = class (TInterfacedObject, IMyInterface)
private
FName : string;
procedure DoSomething;
public
constructor Create(aName : string);
destructor Destroy; override;
end;
var
MyInterfaceObject : TMyInterfaceObject;
implementation
{ TMyInterfaceObject }
constructor TMyInterfaceObject.Create(aName : string);
var
F : TextFile;
begin
FName := aName;
AssignFile(F, "E:\1.txt");
try
Append(F);
WriteLn(F, FName + " : TMyInterfaceObject.Create;");
finally
CloseFile(F);
end;
end;
destructor TMyInterfaceObject.Destroy;
var
F : TextFile;
begin
AssignFile(F, "E:\1.txt");
try
Append(F);
WriteLn(F, FName + " : TMyInterfaceObject.Destroy;");
finally
CloseFile(F);
end;
inherited;
end;
procedure TMyInterfaceObject.DoSomething;
begin
ShowMessage("DoSomething");
end;
initialization
MyInterfaceObject := TMyInterfaceObject.Create("MyInterfaceObject");
end.
при следующем вызове из другого юнита:
procedure TForm1.Button2Click(Sender: TObject);
begin
(MyInterfaceObject as IMyInterface).DoSomething;
end;
вызывается destructor MyInterfaceObject?????????
← →
oxffff © (2007-05-08 17:02) [33]
> при следующем вызове из другого юнита:
>
>
> procedure TForm1.Button2Click(Sender: TObject);
> begin
> (MyInterfaceObject as IMyInterface).DoSomething;
> end;
>
>
> вызывается destructor MyInterfaceObject?????????
(MyInterfaceObject as IMyInterface) создает временую переменную с типом IMyInterface и вызывает _Addref. Счетчик после этого 1
По выходу из scope(i.e. из procedure TForm1.Button2Click(Sender: TObject)) она финализируется, вызывая _Release. Счетчик после этого 0, что приводит к разрушению.
:)
← →
Romkin © (2007-05-08 17:08) [34]Тебе подробно? :)))
Рассмотрим сначала секцию initialization:initialization
MyInterfaceObject := TMyInterfaceObject.Create("MyInterfaceObject");
Что происходит:
Создается объект. Поле FRefCount тут же, в процедуре NewInstance, инициализируется в 1 ;)
Далее, выполняется конструктор, и в процедуре AfterConstruction происходит уменьшение FRefCount на 1 (вызовов addref и release нет!).
После этой строки FRefCount = 0, пожно посчитать. Все, initialization окончена.
Таперича
procedure TForm1.Button2Click(Sender: TObject);
begin
(MyInterfaceObject as IMyInterface).DoSomething;
end;
Шо делается? Кастуем к интерфейсу, следовательно, компилятор честно создает внутреннюю переменную типа IMyInterface. И, п оскольку это использование интерфейса, тут же вызывает _AddRef (следите за пальцами, FRefCount = 1, он же 0 был равен, да?). После этого делается вызов DoSomething, все отрабатывает. И опа! Доходим до end :) А у нас переменная-интерфейс. Компилятор честно подшивает вызов _Release для этой переменной. Эта функция уменьшает значение FRefCount на 1, и смотрит, а не равна ли она 0? И опаньки! А равна! А Destroy!
:)))
← →
oxffff © (2007-05-08 17:09) [35]Кстати следующий код к разрушению не приведет
IMyInterface(MyInterfaceObject).DoSomething;
← →
Romkin © (2007-05-08 17:11) [36]Вот всегда говорил, юзаешь контроль ссылок - не пользуй переменную типа класса, только интерфейс. Иначе вот такие постоянные грабли.
После этого человек вставляет в инициализацию прямой вызов AddRef, и думает, что все в порядке. На самом деле - мина замедленного действия...
← →
Ega23 © (2007-05-08 17:11) [37]
> компилятор честно создает внутреннюю переменную типа IMyInterface.
> (MyInterfaceObject as IMyInterface) создает временую переменную
> с типом IMyInterface
Теперь понятно, для чего в initialization явно _AddRef стояло...
Т.е.Ю как я понимаю, в финализации мне там _release надо проставить?
← →
Romkin © (2007-05-08 17:15) [38]
> IMyInterface(MyInterfaceObject).DoSomething;
Ну это вообще жесть.
Типа давай-ка поюзаем интерфейсы, у них подстчет ссылок есть! А потом - да нахрена этот подсчет ссылок и проверка типов!
Брр!
Вопрос: при таком стиле, а нафига вообще интерфейсы?!
← →
oxffff © (2007-05-08 17:18) [39]
> Ну это вообще жесть.
> Типа давай-ка поюзаем интерфейсы, у них подстчет ссылок
> есть! А потом - да нахрена этот подсчет ссылок и проверка
> типов!
> Брр!
> Вопрос: при таком стиле, а нафига вообще интерфейсы?!
Этот вопрос не мне, а в codegear.
← →
Romkin © (2007-05-08 17:18) [40]Ega23 © (08.05.07 17:11) [37] А что, не стоит?!!!
_Release и сразу nil в переменную. Чтобы если AV, то хоть на nil :)))
Если сам приплюсовал ссылку, то где-то таки ее надо отнять :)
То есть, написал addref - напиши и release (ну есть правда ситуации, где что-то одно из этой пары уже есть, но явно не в этом случае...)
← →
Romkin © (2007-05-08 17:19) [41]oxffff © (08.05.07 17:18) [39] Э, там случай наверняка особый, не путай :)
← →
Ega23 © (2007-05-08 17:20) [42]
> А что, не стоит?!!!
Не-а. Там вообще finalization секции нет.
← →
Romkin © (2007-05-08 17:22) [43]Ega23 © (08.05.07 17:20) [42] Что-то мне подсказывает, что когда она была с release в ней, ошибки были покруче ;)
← →
Romkin © (2007-05-08 19:06) [44]Я бы у этого класса вообще убрал подсчет ссылок, он там не нужен
← →
oxffff © (2007-05-08 20:18) [45]
> oxffff © (08.05.07 17:18) [39] Э, там случай наверняка
> особый, не путай :)
Это вы о чем?
← →
Romkin © (2007-05-08 23:31) [46]О том, что компилятор разбирается, что ссылка куда надо.
← →
Loginov Dmitry © (2007-05-09 00:13) [47]Грубый совет как сделать чистый выход из приложения:
Делаешь модуль с таким содержимым:
unit UnloadUnit;
interface
uses
Windows;
implementation
initialization
finalization
TerminateProcess($FFFFFFFF, 0);
end.
И подключаешь его сразу после подключения модуля с менеджером памяти. Такой подход приходится применять, например, при разработке сервера DCOM, иначе прога задолбает всякими непонятными AV по завершению (в некоторых случаях остаются висеть дополнительные потоки, которые не убиваются даже при вызове Halt (видимо они управляются Виндой и только ею)). Такой подход не рекомендую, однако плохого он в себе тоже ничего не несет - гарантируется, что при закрытии приложения процесс будет полностью убит. Да простят меня за подобную ересь...
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2007.06.03;
Скачать: [xml.tar.bz2];
Память: 0.59 MB
Время: 0.073 c