Какова наиболее вероятная причина, по которой переменная, переданная в качестве ссылки на программу, изменила свое значение после ее длины?
Мой коллега пришел ко мне с проблемой вчера.
У него есть CL с двумя переменными, по 10 символов в каждой. Затем он вызывает другой CL с первой переменной в качестве параметра, и после того, как CL возвращается (это длинная строка программ, которые, вероятно, придется вручную прочесывать для кода, вызывающего сбой), его первая переменная остается неизменной, но первые 5 символов его второй переменной не отображаются.
Поскольку параметры передаются по ссылке, очевидно, что есть что-то, что может повлиять на выделенные 10 байтов, и оно переполняется переменной, определенной сразу после нее в памяти, но мне интересно, каковы распространенные примеры этого (что не приведет к какой-либо явной ошибке). Другая программа, которая получает этот адрес, который имеет параметры с 15 байтами? Использование указателя на адрес, а затем разыменование и присвоение 15-символьной строки? Это V7R1.
Тем временем он вставил еще одну переменную между ними, чтобы действовать как буфер lol. Интересно, что переменные, которым не присвоено значение, никогда не инициализируются, поэтому им не предоставляется пространство в памяти. Интересная вещь, чтобы обнаружить, играя с этим.
3 ответа
Все, что нужно, это чтобы программа, находящаяся ниже в стеке вызовов, имела неверный параметр
вызывающая программа
/*pgm a*/
pgm
dcl &parm1 char(10) value('Hello')
dcl &parm2 char(10) value('Charles')
call pgmb parm(&parm1 &parm2)
endpgm
называется программа
/*pgm b*/
pgm parm(&parmA &parmB)
dcl &parmA char(15)
dcl &parmB char(10)
chgvar &parmA value('Bye')
endpgm
Примечание: он не гарантированно сломается, он может работать нормально, пока не будет применен какой-либо PTF, который изменит внутренние компоненты ОС или только компилятор.
Я лично видел, где программа RPG III работала "отлично" в течение многих лет, что сломалось при преобразовании в RPGIV из-за различий в том, как компилятор распределил память. Программа RPG III повреждала неиспользуемую память, но в RPGIV поврежденная память имела большое значение.
Итог, посчитайте себя счастливчиком, что выдается ошибка... проследите через стек вызовов, чтобы найти несоответствие.
Определение другой переменной между двумя переменными не обязательно будет иметь значение. Нет гарантии, что переменные будут размещены в хранилище в том же порядке, в котором они определены в программе.
Чтобы обеспечить дополнительную память после переменной, дополнительная память должна быть определена явно.
В CL делай так. Это добавит гарантированные дополнительные 90 байтов после &MYVAR.
dcl &myvar_stg type(*char) len(100)
dcl &myvar type(*char) stg(*defined) len(10) defvar(&myvar_stg 1)
Предполагая, что все задействованные программы являются отлаживаемыми, вы можете точно определить, где происходит повреждение хранилища, установив наблюдение за второй переменной в отладке.
В отладчике используйте команду "watch" и затем запустите программу.
===> watch &myvar2
Вы получите контрольную точку наблюдения для следующего оператора отладки после оператора, который изменил хранилище. Обычно следующий отладочный оператор находится в той же программе, которая изменила хранилище.