AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 06.07.2016, 10:43   #1  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Рекурсия. Глюк отладчика.
Привет всем.
Пришлось на днях отлаживать рекурсивный алгоритм в аксапте.
Обнаружил что отладчик некорректно отображает стек вызова в случае рекурсии.
Построил простой пример.
Джоб дергает метод TestA()
Метод TestA() дергает TestB()
Метод TestB() дергает TestA()

Когда весь вызов падает по достижении глубины стека в 400, то в сообщении об ошибке видна корректная последовательность вызовов. А в отладчике видно только 2 метода и все. Досадно.

Вызов xSession::xppCallStack() дает корректный результат.

Проверял на ax2009
Миниатюры
Нажмите на изображение для увеличения
Название: DebuggerRecurseBug.png
Просмотров: 592
Размер:	106.9 Кб
ID:	10878  
За это сообщение автора поблагодарили: Ruff (2), gl00mie (2), handy-comp (2).
Старый 06.07.2016, 11:03   #2  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Как это лечить.
Если работает в классе, то можно в ClassDeclaration завести переменные

X++:
    boolean     debugMode;
    container   curStackTrace;
и пишем метод

X++:
str toString()
{
    ;
    if (debugMode)
    {
        curStackTrace = xSession::xppCallStack();
    }
    // return super(); // нужен в зависимости от наличия родительского класса
    return ""; // нужен в зависимости от наличия родительского класса
}
затем в отладчике там где нам надо правим значение переменной debugMode в true и далее при отладке на каждом шаге ядро дергает нам toString() и мы не заходя в него видим актуальный стек вызова в контейнере curStackTrace

Последний раз редактировалось Logger; 06.07.2016 в 11:41.
Старый 06.07.2016, 13:23   #3  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
В 2012-й та же фигня.
Старый 06.07.2016, 13:29   #4  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Мне кажется, в Х++ использование рекурсии - сравнительно редко используемый сценарий в силу ряда ограничений (включая макс. глубину стека вызовов в 400 уровней). Обычно для предотвращения бесконечной рекурсии используется некий "контекст", который явно или неявно передается между вызовами, к примеру, это может быть множество посещенных узлов или что-либо подобное. В отладчике можно отслеживать такой "контекст", чтобы понимать, что рекурсивно уже было обработано, а что - нет.
Старый 06.07.2016, 14:03   #5  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Собственно так и делаю. Переписываю алгоритм без рекурсии.

P.S.
Надо будет CIL попробовать. Там предел для рекурсии должен быть намного выше 400 уровней.
Старый 06.07.2016, 14:09   #6  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
В CIL по идее предел для рекурсии должен быть обусловлен доступным местом в стеке потока - по умолчанию это 10 Мб.
За это сообщение автора поблагодарили: Logger (3).
Старый 07.07.2016, 10:21   #7  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Набросал класс GRD_StackTrace
Положил его в ClassDeclaration класса Info и инициализирую в методе New().

Теперь, если есть сомнения в корректности отображаемого в отладчике стека вызовов, то прямо в отладчике нахожу экземпляр Infolog (он всегда доступен), нахожу в нем переменную с типом GRD_StackTrace, меняю в ней свойство debugMode на true и при дальнейшей отладке вижу стек вызовов в переменной массиве aStackTrace.
Удобно.

P.S.
Интересно, что если добавить GRD_StackTrace в класс Application то не работает. Почему, пока не разобрался.
Миниатюры
Нажмите на изображение для увеличения
Название: DebuggerRecurseBug2.png
Просмотров: 510
Размер:	102.7 Кб
ID:	10880  
Вложения
Тип файла: zip Class_GRD_StackTrace_2016_07_07_10_13_NEW_DEV.zip (1,016 байт, 191 просмотров)

Последний раз редактировалось Logger; 07.07.2016 в 10:43.
За это сообщение автора поблагодарили: Мартынов Дмитрий (2).
Старый 07.07.2016, 12:41   #8  
alex55 is offline
alex55
MCTS
MCBMSS
 
224 / 145 (5) +++++
Регистрация: 13.02.2007
Адрес: Москва
Цитата:
Сообщение от Logger Посмотреть сообщение
Собственно так и делаю. Переписываю алгоритм без рекурсии.

P.S.
Надо будет CIL попробовать. Там предел для рекурсии должен быть намного выше 400 уровней.
Насколько я помню в CIL было другое ограничение - встроенные методы не могли рекурсивно вызывать себя.
Старый 09.07.2016, 11:32   #9  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от alex55 Посмотреть сообщение
Насколько я помню в CIL было другое ограничение - встроенные методы не могли рекурсивно вызывать себя.
Здесь фигня в том что метод не сам себя вызывает а через другой метод. Сокращени стека вызовов при этом совсем не в тему и неочевидно.
Я думаю это глюк.
Старый 03.05.2018, 15:19   #10  
kitty is offline
kitty
Участник
 
370 / 30 (2) +++
Регистрация: 24.05.2005
Цитата:
Сообщение от alex55 Посмотреть сообщение
Насколько я помню в CIL было другое ограничение - встроенные методы не могли рекурсивно вызывать себя.

"встроенные" методы - это локальный метод функции?
У меня выдается предупреждение:
Warning: Recursive local methods are not supported in X++ CIL
Я хочу понять, мне нужно нужно вообще метод переписать без использования рекурсии или достаточо просто "разделить" рекурсию на два метода A и B - вызывать из A метод B, а из B вызывать А .(таким образом, удовлетворив требование про отсутствие "встроенных методов")
Старый 03.05.2018, 15:44   #11  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Насколько я помню, он предупреждение пишет, но все компиляет и работает.
Если есть сомнения - просто попробуйте тестовый метод сделать и запустить.

Кстати, в последних версиях C# разрешили делать локальные методы.
Старый 08.05.2018, 12:04   #12  
eugene egorov is offline
eugene egorov
Участник
Аватар для eugene egorov
 
273 / 97 (4) ++++
Регистрация: 05.06.2002
Адрес: Москва
Реально локальные методы с рекурсией в них несовместима с CIL. Сам воткнулся в такую фигню - пишет в логах что метод не существует. CIL три раза перестраивал, код выучил наизусть. Без CIL работает, а в пакетнике валится.
Понять нельзя - нужно просто запомнить.
__________________
любитель портвейна и снов с прокисшей капустой в усах
Старый 08.05.2018, 12:11   #13  
kitty is offline
kitty
Участник
 
370 / 30 (2) +++
Регистрация: 24.05.2005
Я рекурсию оставила. Вынесла локальный метод в отдельный метод-член класса.
Теги
bug, debugger, recursion, баг, отладчик, рекурсия

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Глюк с таблицей RpayHRMOrganization в DAX2009 d_alexe DAX: Программирование 12 24.09.2013 10:04
Глюк. "Выбрать компанию" в гриде только одна строка Poleax DAX: Администрирование 10 06.07.2011 13:17
Глюк RunBase (AX40sp2) Alexx7 DAX: Программирование 7 22.01.2010 10:59
Глюк с RecId greench DAX: Программирование 20 24.10.2007 14:59
Глюк автоматическое рассопопоставление Logger DAX: Функционал 4 14.07.2006 10:09
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 03:39.