|  06.07.2016, 10:43 | #1 | 
| Участник | Рекурсия. Глюк отладчика. 
			
			Привет всем. Пришлось на днях отлаживать рекурсивный алгоритм в аксапте. Обнаружил что отладчик некорректно отображает стек вызова в случае рекурсии. Построил простой пример. Джоб дергает метод TestA() Метод TestA() дергает TestB() Метод TestB() дергает TestA() Когда весь вызов падает по достижении глубины стека в 400, то в сообщении об ошибке видна корректная последовательность вызовов. А в отладчике видно только 2 метода и все. Досадно. Вызов xSession::xppCallStack() дает корректный результат. Проверял на ax2009 | 
|  | |
| За это сообщение автора поблагодарили: Ruff (2), gl00mie (2), handy-comp (2). | |
|  06.07.2016, 11:03 | #2 | 
| Участник | 
			
			Как это лечить. Если работает в классе, то можно в ClassDeclaration завести переменные X++:     boolean     debugMode;
    container   curStackTrace;X++: str toString() { ; if (debugMode) { curStackTrace = xSession::xppCallStack(); } // return super(); // нужен в зависимости от наличия родительского класса return ""; // нужен в зависимости от наличия родительского класса } Последний раз редактировалось Logger; 06.07.2016 в 11:41. | 
|  | 
|  06.07.2016, 13:23 | #3 | 
| Участник | 
			
			В 2012-й та же фигня.
		 | 
|  | 
|  06.07.2016, 13:29 | #4 | 
| Участник | 
			
			Мне кажется, в Х++ использование рекурсии - сравнительно редко используемый сценарий в силу ряда ограничений (включая макс. глубину стека вызовов в 400 уровней). Обычно для предотвращения бесконечной рекурсии используется некий "контекст", который явно или неявно передается между вызовами, к примеру, это может быть множество посещенных узлов или что-либо подобное. В отладчике можно отслеживать такой "контекст", чтобы понимать, что рекурсивно уже было обработано, а что - нет.
		 | 
|  | 
|  06.07.2016, 14:03 | #5 | 
| Участник | 
			
			Собственно так и делаю. Переписываю алгоритм без рекурсии. P.S. Надо будет CIL попробовать. Там предел для рекурсии должен быть намного выше 400 уровней. | 
|  | 
|  06.07.2016, 14:09 | #6 | 
| Участник | 
			
			В CIL по идее предел для рекурсии должен быть обусловлен доступным местом в стеке потока - по умолчанию это 10 Мб.
		 | 
|  | |
| За это сообщение автора поблагодарили: Logger (3). | |
|  07.07.2016, 10:21 | #7 | 
| Участник | 
			
			Набросал класс GRD_StackTrace Положил его в ClassDeclaration класса Info и инициализирую в методе New(). Теперь, если есть сомнения в корректности отображаемого в отладчике стека вызовов, то прямо в отладчике нахожу экземпляр Infolog (он всегда доступен), нахожу в нем переменную с типом GRD_StackTrace, меняю в ней свойство debugMode на true и при дальнейшей отладке вижу стек вызовов в переменной массиве aStackTrace. Удобно. P.S. Интересно, что если добавить GRD_StackTrace в класс Application то не работает. Почему, пока не разобрался. Последний раз редактировалось Logger; 07.07.2016 в 10:43. | 
|  | |
| За это сообщение автора поблагодарили: Мартынов Дмитрий (2). | |
|  07.07.2016, 12:41 | #8 | 
| MCTS | |
|  | 
|  09.07.2016, 11:32 | #9 | 
| Участник | |
|  | 
|  03.05.2018, 15:19 | #10 | 
| Участник | Цитата: "встроенные" методы - это локальный метод функции? У меня выдается предупреждение: Warning: Recursive local methods are not supported in X++ CIL Я хочу понять, мне нужно нужно вообще метод переписать без использования рекурсии или достаточо просто "разделить" рекурсию на два метода A и B - вызывать из A метод B, а из B вызывать А .(таким образом, удовлетворив требование про отсутствие "встроенных методов") | 
|  | 
|  03.05.2018, 15:44 | #11 | 
| Участник | 
			
			Насколько я помню, он предупреждение пишет, но все компиляет и работает. Если есть сомнения - просто попробуйте тестовый метод сделать и запустить. Кстати, в последних версиях C# разрешили делать локальные методы. | 
|  | 
|  08.05.2018, 12:04 | #12 | 
| Участник | 
			
			Реально локальные методы с рекурсией в них несовместима с CIL. Сам воткнулся в такую фигню - пишет в логах что метод не существует. CIL три раза перестраивал, код выучил наизусть. Без CIL работает, а в пакетнике валится. Понять нельзя - нужно просто запомнить. 
				__________________ любитель портвейна и снов с прокисшей капустой в усах | 
|  | 
|  08.05.2018, 12:11 | #13 | 
| Участник | 
			
			Я рекурсию оставила. Вынесла локальный метод  в отдельный метод-член класса.
		 | 
|  | 
| Теги | 
| bug, debugger, recursion, баг, отладчик, рекурсия | 
|  | 
|  Похожие темы | ||||
| Тема | Ответов | |||
| Глюк с таблицей RpayHRMOrganization в DAX2009 | 12 | |||
| Глюк. "Выбрать компанию" в гриде только одна строка | 10 | |||
| Глюк RunBase (AX40sp2) | 7 | |||
| Глюк с RecId | 20 | |||
| Глюк автоматическое рассопопоставление | 4 | |||
| 
 |