Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.06.03;
Скачать: CL | DM;

Вниз

Подскажите софтину   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.04 c
1-1175705210
Углук
2007-04-04 20:46
2007.06.03
Шкала в TCharte


2-1179315922
thvfrjd
2007-05-16 15:45
2007.06.03
Отчет QuickReport


2-1179294807
Krot
2007-05-16 09:53
2007.06.03
запуск своей программы с ключом


1-1175861729
Wahnsinng
2007-04-06 16:15
2007.06.03
Как отключить сообщение об ошибках


15-1178289310
Cyrax
2007-05-04 18:35
2007.06.03
Microsoft Visual C++ Runtime Library: Runtime error