Форум: "Прочее";
Текущий архив: 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 (ну есть правда ситуации, где что-то одно из этой пары уже есть, но явно не в этом случае...)
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2007.06.03;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.046 c