Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Обычная тема Падает 1С++ (число прочтений - 2395 )
orefkov
1c++ developer
1c++ moderator
Отсутствует


I Love YaBB 2!

Сообщений: 896
Зарегистрирован: 20. Мая 2006
Падает 1С++
13. Марта 2009 :: 10:41
Печать  
Вот пример и тест.

defcls:

Код
Выбрать все
класс Класс1 = класс1@md
{
};

класс Класс2 = класс2@md : Класс1
{
};
 



Класс1:
Код
Выбрать все
Функция Сам(К) Возврат К; КонецФункции	// Сам

Процедура Конструктор()
	Сообщить("Класс1 ктр");
КонецПроцедуры	// Конструктор

Процедура Деструктор()
	Сообщить("Класс1 дтр");
КонецПроцедуры	// Деструктор

Процедура вызов() Экспорт
	Сообщить("Класс1 вызов");
КонецПроцедуры	// вызов

Процедура Тест() Экспорт
	Сам(Контекст).вызов();
КонецПроцедуры	// Тест 



Класс2
Код
Выбрать все
Процедура Конструктор()
	Сообщить("Класс2 ктр");
КонецПроцедуры	// Конструктор

Процедура Деструктор()
	Сообщить("Класс2 дтр");
КонецПроцедуры	// Деструктор
 



ГМ:
Код
Выбрать все
Процедура ПриНачалеРаботыСистемы()
	ЗагрузитьВнешнююКомпоненту(КаталогИБ() + "1cpp.dll");
	а = СоздатьОбъект("Класс2");
	б = а.ПолучитьБазовыйКласс("Класс1");
	а = 0;
	Предупреждение("Ща вызовем", 2);
	б.Тест();
КонецПроцедуры	// ПриНачалеРаботыСистемы 



При запуске видим:
Код
Выбрать все
Класс1 ктр
Класс2 ктр
Класс2 дтр
 


и вылетаем (на любой версии 1С++).

тест конфа в аттаче.
  

IcppTest.zip ( 4 KB | Загрузки )
Наверх
 
IP записан
 
orefkov
1c++ developer
1c++ moderator
Отсутствует


I Love YaBB 2!

Сообщений: 896
Зарегистрирован: 20. Мая 2006
Re: Падает 1С++
Ответ #1 - 13. Марта 2009 :: 10:54
Печать  
2 Артур.
В чем там баг я вроде как разобрался.
Надо бы архитектуру поправить чуть.
После того, как объект-КОП создан, все входящие в него базовые объекты-КОПы должны перенаправлять свои IncRef/DecrRef конечному объекту (в данном тесте при создании объекта Класс2 входящий в него объект Класс1 должен все IncrRef/DecrRef пересылать объекту Класс2). Когда счетчик ссылок конечного объекта обнуляется, все входящие в него базовые КОПы должны "отвязаться" от него, и считать ссылки самостоятельно. В данном тесте после

а = 0;

будут живы как объект Класс1, так и Класс2, и Класс1 спокойно может обращаться к Сам(Контекст).

Попутно надо рассмотреть ситуацию - в вызове деструктора объект сохраняет ссылку на себя (Контекст) в глобальную переменную.
Тоже возможны косяки как с подсчетом ссылок, так и при дальнейшем вызове методов у этой глобальной переменной.

  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Падает 1С++
Ответ #2 - 13. Марта 2009 :: 11:11
Печать  
Падение подтверждаю.

НО аналогичный тест с удалением наследника и использования только базы давно есть в конфе тестирования 1С++, на текущих конфах падения конфы не было Печаль
Соответствующая ошибка в 1С++ также давно была исправлена.

ЗЫ тестирование давно не запускал, пока не до того Печаль
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Падает 1С++
Ответ #3 - 13. Марта 2009 :: 11:15
Печать  
Вот тесты
Цитата:
Процедура ТестДеструкторПотомкаРаньшеЧемДеструкторПредка() Экспорт
  Перем Объект;

  Объект = СоздатьОбъект("ООППотомок");
  Объект1 = Объект.ПолучитьБазовыйКласс("");
  Объект = Объект1;
КонецПроцедуры

Процедура ТестУдалениеПотомкаРаньшеПредка() Экспорт
  Объект = СоздатьОбъект("ООППотомок");
  Объект = Объект.ПолучитьБазовыйКласс("");
КонецПроцедуры      // ТестУдалениеПотомкаРаньшеПредка

Процедура ТестУдалениеПотомкаРаньшеПредка2() Экспорт
  Объект = СоздатьОбъект("ООППотомок");
  Объект1 = Объект.ПолучитьБазовыйКласс("");
КонецПроцедуры      //

Процедура ТестУдалениеПотомкаРаньшеПредкаИЧтениеАтрибутаБазовогоКласса() Экспорт
  Сам = Сам();

  Объект = СоздатьОбъект("ООППотомок");

  Объект.АтрибутБазовогоКласса = 10;
  Объект1 = Объект.ПолучитьБазовыйКласс("");

  Сам.ПроверитьРавенство(Объект.АтрибутБазовогоКласса, 10);
  Сам.ПроверитьРавенство(Объект1.АтрибутБазовогоКласса, 10);

  Объект = "";

  Сам.ПроверитьРавенство(Объект1.АтрибутБазовогоКласса, 10);

КонецПроцедуры      // ТестУдалениеПотомкаРаньшеПредка

Процедура Тест_ВызовЭкспортнойФункцииИзДеструктораПредкаУжеПослеДеструктораПотомка() Экспорт
     Объект = СоздатьОбъект("ООППотомок");
     Объект.ФлагВызыватьСвоюЭкспортнуюФункциюЧерезСамВДеструкторе = 1;
     Журнал = Объект.ПолучитьЖурналВызовов();

     Объект="";
     Сам().ПроверитьРавенство(Журнал.стрЖурнал, "ООППредок::Конструктор, ООППотомок::Конструктор, ООППредок::ПолучитьЖурналВызовов, ООППотомок::Деструктор, ООППредок::ОткрытаяФункция, ООППредок::Деструктор");
КонецПроцедуры

Процедура Тест_ВызовЭкспортногоСвойстваИзДеструктораПредкаУжеПослеДеструктораПотомка() Экспорт
     Объект = СоздатьОбъект("ООППотомок");
     Объект.ФлагВызыватьСвоеЭкспортноеСвойствоЧерезСамВДеструкторе = 1;
     Журнал = Объект.ПолучитьЖурналВызовов();

     Объект="";
     Сам().ПроверитьРавенство(Журнал.стрЖурнал, "ООППредок::Конструктор, ООППотомок::Конструктор, ООППредок::ПолучитьЖурналВызовов, ООППотомок::Деструктор, ООППредок::АтрибутБазовогоКласса<2>, ООППредок::Деструктор");
КонецПроцедуры

Процедура Тест_ТипЗначенияСтрИзДеструктораПредкаУжеПослеДеструктораПотомка() Экспорт
     Объект = СоздатьОбъект("ООППотомок");
     Объект.ФлагПолучитьТипЗначенияСтрЧерезСамВДеструкторе = 1;
     Журнал = Объект.ПолучитьЖурналВызовов();

     Объект="";
     Сам().ПроверитьРавенство(Журнал.стрЖурнал, "ООППредок::Конструктор, ООППотомок::Конструктор, ООППредок::ПолучитьЖурналВызовов, ООППотомок::Деструктор, ООППредок::ТипЗначенияСтр<ООППредок>, ООППредок::Деструктор");
КонецПроцедуры
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Падает 1С++
Ответ #4 - 13. Марта 2009 :: 11:21
Печать  
А если вместо Тест() добавить использование Экспортной переменной, то 1С уже не падает Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
orefkov
1c++ developer
1c++ moderator
Отсутствует


I Love YaBB 2!

Сообщений: 896
Зарегистрирован: 20. Мая 2006
Re: Падает 1С++
Ответ #5 - 13. Марта 2009 :: 11:27
Печать  
Вся фишка в том, что в вызываемом методе идет обращение к Сам(Контекст).ВызовМетодаИлиОбращениеКПеременной

Ведь для модулей базовых классов Контекст назначается равным конечному, наследуемому классу, для возможности виртуального вызова методов. А тут получается, что в базовом классе Контекст ссылается на уже удаленный участок памяти.
  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Падает 1С++
Ответ #6 - 13. Марта 2009 :: 11:38
Печать  
Лично у меня пока все равно нету времени заниматься 1С++ - месяц точно Печаль
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать