Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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
4-1167142342
MasteroK
2006-12-26 17:12
2007.06.03
Как извлечь из буфера обмена первые N символов текста.


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


1-1175692720
Romkin
2007-04-04 17:18
2007.06.03
RichEdit, гиперссылки


15-1178537912
Рамиль
2007-05-07 15:38
2007.06.03
Кто нибудь делал фотокниги


15-1177956967
Wiedzmin
2007-04-30 22:16
2007.06.03
Смена иконки стороннего приложения





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский