Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Горячая тема (более 10 ответов) Баг 1С со значением, возвращаемым из функции (число прочтений - 6673 )
artbear
1c++ developer
1c++ moderator
Отсутствует


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

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Баг 1С со значением, возвращаемым из функции
05. Июня 2008 :: 05:53
Печать  
Народ, у 1С есть серьезная бага, связанная с сабжем.
http://www.1cpp.ru/bugs/show_bug.cgi?id=3903

artbear писал(а) 04. Июня 2008 :: 14:30:
Интереснейший баг/фича/факт нарисовался при реализации этих функций.
Код С++
Код
Выбрать все
int  CComponentClassImpl::CallAsFunc(int iMethNum,CValue & rValue,CValue * *ppValue)
{
	if(iMethNum==iNumOfSpecialMethod_Virt)
	{
		rValue.AssignContext(CBLModuleWrapper::GetContextFromModule(m_pMod));
		return TRUE;
	}
 


Неверно работает, если в классе определить функцию
Код
Выбрать все
Функция ПолучитьКонтекст() Экспорт
	Возврат вирт();
КонецФункции
 


и вызвать в тестовом коде как Объект.ПолучитьКонтекст() несколько раз, хотя бы пару.
Все, баг обеспечен, второй и последующие вызовы дадут пустой объект Печаль

Долго думал Печаль
Но все-таки разобрался Улыбка
Правильный вариант
Код
Выбрать все
int  CComponentClassImpl::CallAsFunc(int iMethNum,CValue & rValue,CValue * *ppValue)
{
	if(iMethNum==iNumOfSpecialMethod_Virt)
	{
		rValue.Reset(); // Вот оно !!
		CBLContext* pCont = CBLModuleWrapper::GetContextFromModule(m_pMod);
		rValue.AssignContext(pCont);

		return TRUE;
	}
 



Нужно подумать насчет подобной реализации внутри различных методов классов 1С++
Приходит на память Палыч и его пожиратель памяти, похожая бага Улыбка



orefkov писал(а) 05. Июня 2008 :: 05:26:
Насчет Reset это точно.
С trad'ом как-то разбирались с подобной фигней.
Выяснили, что при вызове функций движок 1С использует для retVal статический объект CValue. И это приводит к разным траблам. Например, если мы в своем методе присвоили retVal ссылку на контекст, а потом сгенерили RuntimeError, то так как retVal статическая, а не на стеке, для нее не вызывается деструктор, и на тот контекст (который записывали в retVal), ссылка сохраняется, до того момента, пока 1С не вызовет какой-либо другой метод, в котором retVal присвоится другое значение. А в случаях, когда в коде 1С пишут Возврат ВызовНекойФункции(); , ссылки на объекты могут вообще считаться криво.


Поэтому внутри вызовов CallAsFunc для своих контекстов нужно обязательно делать RetValue.Reset, иначе могут пойти различные косяки

ИМХО нужно пересмотреть реализации вызовов функций различных классов в 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С со значением, возвращаемым из функции
Ответ #1 - 05. Июня 2008 :: 06:48
Печать  
Тема Палыча про пожиратель памяти "Не освобождается память"
http://itland.ru/forum//index.php?showtopic=820&hl=%EF%EE%E6%E8%F0%E0%F2%E5%EB%F...

Я правильно вспомнил, абсолютно те же симпомы Печаль
  

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С со значением, возвращаемым из функции
Ответ #2 - 23. Июля 2008 :: 09:10
Печать  
Нарисовался еще один интереснейший баг/фича при работе с 1С.
Пишем код:
Код
Выбрать все
Список = СоздатьОБъект("СписокЗначений");
Список = ПолучитьПустоеЗначение(); // не указываем тип
//или Список = ПолучитьПустоеЗначение(""); // не указываем тип
 


Далее передаем это значение (Список) в 1С++ в любой метод, который должен работать с контекстом.
Как правило, в подобных методах на С++ написана спец.проверка на наличие контекста
Код
Выбрать все
CBLContext* pCont = pValue->GetContext();
if (!pCont)
  RuntimeError("ошибка"); 



Так вот, если передать именно Список с пустым, казалось бы, значением, то указанный код проверки не сработает !!
Т.е. тип переданного значения (CValue::type == 0), а поле контекста не сбросилось, и указывает на предыдущее значение, т.е. СписокЗначений !!

Если же в ПолучитьПустоеЗначение() указать любой тип, хоть Число, хоть Строка и т.д, то баг пропадает Улыбка

Вывод - ПолучитьПустоеЗначение() нельзя использовать с пустым телом, т.е. у 1С здесь недоработка Печаль и очень опасная фича.
Вы
  

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


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Баг 1С со значением, возвращаемым из функции
Ответ #3 - 23. Июля 2008 :: 17:30
Печать  
artbear

Я правильно понимаю, что AssignContext() может лажать в случае, если у CValue уже установлен контекст?
Или присваивание контекста не происходит в каких-то других случаях?
Или контекст присваивается, но тип объекта не меняется?
Можешь слегка уточнить симптоматику?

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

De quelle planète es-tu?
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


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

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Баг 1С со значением, возвращаемым из функции
Ответ #4 - 24. Июля 2008 :: 03:09
Печать  
Используя вышенаписанные 2 строчки кода 1С, получаем, что тип объекта в CValue меняется, но поле контекста не сбрасывается Печаль
В итоге простое GetContext() дает совершенно неверный контекст Печаль
А в обычных случаях пока ничего подобного не замечал.
Т.е. налицо баг реализации ПолучитьПустоеЗначение()
  

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


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Баг 1С со значением, возвращаемым из функции
Ответ #5 - 24. Июля 2008 :: 05:05
Печать  
artbear писал(а) 24. Июля 2008 :: 03:09:
Используя вышенаписанные 2 строчки кода 1С, получаем, что тип объекта в CValue меняется, но поле контекста не сбрасывается Печаль

Это уже ты про последний случай рассказываешь, с пустым значением.
А мне бы интересно послушать про http://www.1cpp.ru/forum/YaBB.pl?num=1212645215/0#0

Как получается, что вирт() перестает возвращать нужный контекст без Reset()?
  

De quelle planète es-tu?
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


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

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Баг 1С со значением, возвращаемым из функции
Ответ #6 - 24. Июля 2008 :: 05:12
Печать  
Я же привел цитату Саши Орефкова с разъяснением возникновения бага - в моем же первом посте Улыбка
  

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С со значением, возвращаемым из функции
Ответ #7 - 24. Июля 2008 :: 05:15
Печать  
Блин, недопонял тебя Печаль
Счас сформулирую.
  

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С со значением, возвращаемым из функции
Ответ #8 - 24. Июля 2008 :: 05:22
Печать  
В общем, см. цитату от Саши Орефкова - вся фишка в том, что объект RetValue, передаваемый в функции контекстов при их вызове, является статическим Печаль и возникают различные баги с подсчетом ссылок.
Т.е. при вызове плохо написанной функции своего контекста счетчик ссылок не увеличивается, и в какой-то момент вызывается или деструктор или просто объект RetValue очищается без уменьшения количества ссылок на контекст Печаль
  

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


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Баг 1С со значением, возвращаемым из функции
Ответ #9 - 24. Июля 2008 :: 09:29
Печать  
Кстати, Артур

Код
Выбрать все
	Список = СоздатьОбъект("СписокЗначений"); // специально создаю значение !!

	Вектор.Добавить(12);
	Вектор.Добавить(11);
	Вектор.Добавить(10);

	Список = ПолучитьПустоеЗначение(); // так использовать нельзя - http://www.1cpp.ru/forum/YaBB.pl?num=1212645215/2#2 !
	вирт().ПроверитьИсключение(Вектор, "Выгрузить", "Список");
 


Это у меня была сознательная последовательность (хотя и неправильная по синтаксису).
Для того, чтобы тест проходил, тебе надо в CValue2ResultLoader добавить проверку агрегатного типа значения (если ты еще этого не сделал).
  

De quelle planète es-tu?
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


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

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Баг 1С со значением, возвращаемым из функции
Ответ #10 - 24. Июля 2008 :: 11:06
Печать  
kms писал(а) 24. Июля 2008 :: 09:29:
Для того, чтобы тест проходил, тебе надо в CValue2ResultLoader добавить проверку агрегатного типа значения (если ты еще этого не сделал).

А я как раз не хочу добавлять лишние проверки, и не хочу поддерживать ПолучитьПустоеЗначение без параметров или равное пустой строке.
  

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