Изменяется переменная
|
|
kalumb | Дата: Воскресенье, 15 Декабря 2019, 17:38 | Сообщение # 1 |
почетный гость
Сейчас нет на сайте
| Всем привет. У меня что-то странное происходит с переменной. Она изменяется в зависимости он вызова других функций. Код на картинке. Ситуация такая. Функция LoadFile возвращает буфер с прочитанным файлом и записывает в переменную BufferSize его размер. Но потом почему-то эта переменная меняется сама собой. Если в коде оставить функцию printf в зелёной рамке, то переменная изменяется (Вывод 1), а если убрать - значение остаётся прежним (Вывод 2). Размер файла равен 2608 байт. Из-за чего такое может происходить?
Видео: https://yadi.sk/i/MJ1FmIkDHowwLw
Сообщение отредактировал kalumb - Понедельник, 16 Декабря 2019, 00:19 |
|
| |
drcrack | Дата: Воскресенье, 15 Декабря 2019, 17:57 | Сообщение # 2 |
старожил
Сейчас нет на сайте
| симптомы указывают на то, что: 1. размер буфера меньше чем нужно и внутри функции перезаписывается следующая за буфером переменная в памяти (BufferSize) 2. включена оптимизация из-за чего компилятор может менять инструкции местами итд исходя из своих представлений о быстром коде, это и приводит к странному поведению
Сообщение отредактировал drcrack - Воскресенье, 15 Декабря 2019, 17:58 |
|
| |
Dymkens | Дата: Воскресенье, 15 Декабря 2019, 18:04 | Сообщение # 3 |
почетный гость
Сейчас нет на сайте
| Помочь вряд ли смогу, но все ровно назрело пару вопросов. Изменение значения переменной всегда одинаковое (268551192)? Будет ли значение увеличиваться при добавлении нескольких команд printf? И пробовали ли Вы использовать "cout" вместо "printf"?
Моя первая игра - MilvusX
|
|
| |
kalumb | Дата: Воскресенье, 15 Декабря 2019, 18:52 | Сообщение # 4 |
почетный гость
Сейчас нет на сайте
| Dymkens, я изменил первый вывод на это:
Код printf("Size1 File %s = %d\n", Filename, BufferSize-5); Первый вывод: 2603, дальше уже значение другое - 268551108. У меня ниже идут ещё выводы. На переменную там ничего не влияет, но значение изменяется дальше уже на 268551284. Сейчас и без 5 выводит 268551108 во втором выводе. Нет, количество функций printf не влияет на вывод. Код на Си, поэтому cout не пробовал. drcrack, я менял местами объявления переменных, результат тот же. Также я смотрел декомпозированный код в IDA, там всё нормально, все инструкции на своих местах.Добавлено (15 Декабря 2019, 19:27) --------------------------------------------- Помогло добавление ещё одной переменной.
Код DWORD BufferSize1 = 0; ///////////////////////////// Buffer = callbacks.Dll_LoadFile(ExtData, Filename, &BufferSize1); BufferSize = BufferSize1 Но сейчас появились проблемы в других местах. В любом случае такое поведение очень странное.
Сообщение отредактировал kalumb - Воскресенье, 15 Декабря 2019, 18:53 |
|
| |
drcrack | Дата: Воскресенье, 15 Декабря 2019, 19:51 | Сообщение # 5 |
старожил
Сейчас нет на сайте
| покажи лучше код Dll_LoadFile
|
|
| |
kalumb | Дата: Воскресенье, 15 Декабря 2019, 21:29 | Сообщение # 6 |
почетный гость
Сейчас нет на сайте
| Вот видео с отладкой. Я убираю комментарий с вывода - и значение меняется. https://yadi.sk/i/MJ1FmIkDHowwLw
Сообщение отредактировал kalumb - Суббота, 21 Декабря 2019, 02:12 |
|
| |
drcrack | Дата: Воскресенье, 15 Декабря 2019, 23:39 | Сообщение # 7 |
старожил
Сейчас нет на сайте
| попробуй вручную поставить размер буфера скажем в 10000000 и посмотри сохранится ли ошибка
|
|
| |
kalumb | Дата: Понедельник, 16 Декабря 2019, 00:29 | Сообщение # 8 |
почетный гость
Сейчас нет на сайте
| drcrack, ошибка осталась. Вот другой видос из другого куска кода. Тут я вообще ничего не дописываю в исходник, но переменная всё равно меняет значение. https://yadi.sk/i/-aB4eX7629rkJA
|
|
| |
Snake174 | Дата: Понедельник, 16 Декабря 2019, 06:41 | Сообщение # 9 |
участник
Сейчас нет на сайте
| Код printf("Size1 File %s = %u\n", Filename, BufferSize); printf("Size1 File %s = %lu\n", Filename, BufferSize);
Не следует обманывать инспектора Pipmak Assistant Love2D Exporter Love2D-Helpers Old Consoles Games
Сообщение отредактировал Snake174 - Понедельник, 16 Декабря 2019, 08:54 |
|
| |
drcrack | Дата: Понедельник, 16 Декабря 2019, 07:49 | Сообщение # 10 |
старожил
Сейчас нет на сайте
| попробуй другой компилятор
|
|
| |
kalumb | Дата: Понедельник, 16 Декабря 2019, 14:14 | Сообщение # 11 |
почетный гость
Сейчас нет на сайте
| Snake174, проблема не выводе, а в изменении переменной в памяти. Выключил оптимизацию в свойствах проекта, теперь проблемы с переменной len нет. Но первая проблема с выводом не исчезла. Я попробовал обернуть функцию вывода в свою - переменная поменяла значение на 150.
Добавлено (16 Декабря 2019, 23:21) --------------------------------------------- Всё, с проблемой я разобрался. Такое поведение было вызвано несоответствием типов вызывающей программы и DLL. При этом я сам допустил ошибку: запускал отладку в релизной версии, из-за чего и не мог понять, что происходит, т.к. никаких предупреждений от компилятора я не получал. До этого я потратил много времени на компиляцию вызывающей программы, в Debug она так и не запускается (там нужно дописывать пути к заголовкам, что сделал только для релизной версии) :). Так вот при запуске отладчика в Debug режиме после работы функции, которая возвращала буфер, VS выдаёт предупреждение о проблемах с регистром ESP.
В DLL у меня подключался заголовочный файл wintypes.h, в котором были описаны типы (что-то такое: typedef uint32_t DWORD;). А в вызывающей программе использовался стандартный windows.h, который я и прописал в коде библиотеки. Так что для решения проблемы достаточно было поменять одну строку.
Я также определил, на какое значение изменялась моя переменная. В зависимости от кода значения будут разными. Если говорить о моём случае, когда значение менялось из-за вызова printf, то менялось оно на адрес команды после вызова функции (то есть на адрес команды после call). А значение переменной просто “затиралось” в стеке. Вместо printf я пробовал вызывать пустую функцию, которая ничего не возвращает, а на вход принимает int. Результат:
Сейчас всё работает. Спасибо всем за помощь!
Сообщение отредактировал kalumb - Вторник, 17 Декабря 2019, 12:06 |
|
| |
drcrack | Дата: Вторник, 17 Декабря 2019, 03:34 | Сообщение # 12 |
старожил
Сейчас нет на сайте
| кароче классический С++ круто наверно два дня разбираться с багом который прогрессивная часть человечества победила 20 лет назад с разработкой безопасных языков вроде джавы
Сообщение отредактировал drcrack - Вторник, 17 Декабря 2019, 03:34 |
|
| |
kalumb | Дата: Вторник, 17 Декабря 2019, 12:49 | Сообщение # 13 |
почетный гость
Сейчас нет на сайте
| drcrack, ну я бы не назвал это багом. VS же выдаёт предупреждение. Из-за отсутствия опыта в отладке на решение проблемы ушло так много времени.
|
|
| |