Понедельник, 25 Ноября 2024, 11:56

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Изменяется переменная
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 же выдаёт предупреждение. Из-за отсутствия опыта в отладке на решение проблемы ушло так много времени.
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг