Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Раскладка мемберов в дочерней структуре 
:(
    Опции темы
drug007
Дата 1.8.2018, 11:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: нет
Всего: 1



Всем привет!
Работаю над старым проектом с кучей легаси. В процессе рефакторинга перестал работать код, который не менялся и работает уже несколько лет. Выяснилось, что в базовой структуре поле инициализируется как положено, а в дочерней структуре это же поле имеет адрес со смещением 4 байта относительно адреса в базовой структуре и соответственно при первой же записи в это поле происходит повреждение памяти с дальнейшим сегфолтом. Ошибка наблюдается под gcc 4.7.2 и gcc 6.3.0. Куда копать пока не знаю, может кто что подскажет?
PM MAIL   Вверх
drug007
Дата 1.8.2018, 12:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: нет
Всего: 1



По всей видимости проблемы в том, что кто-то портит память, так как изменил порядок членов структуры и сегфолт в совершенно другом месте. Поздравляю себя с увлекательнейшей отладкой на ближайшее время...
PM MAIL   Вверх
xvr
Дата 1.8.2018, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 6939
Регистрация: 28.8.2007
Где: Химки, Московская обл

Репутация: 60
Всего: 221



Цитата(drug007 @  1.8.2018,  11:11 Найти цитируемый пост)
а в дочерней структуре это же поле имеет адрес со смещением 4 байта относительно адреса в базовой структуре

Имеет право

Цитата(drug007 @  1.8.2018,  11:11 Найти цитируемый пост)
и соответственно при первой же записи в это поле происходит повреждение памяти

А вот этого быть не должно. При приведении типов между указателями на базовый и производный класс они (указатели) должны автоматически корректироваться. Покажите код (как пишете в поле)

PM MAIL   Вверх
drug007
Дата 5.8.2018, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: нет
Всего: 1



Спасибо что ответили!
Цитата(xvr @  1.8.2018,  15:27 Найти цитируемый пост)
Имеет право

Я не совсем ясно выразился. Из конструктора дочернего класса вызывается конструктор базового и в конструкторе базового класса мембер имеет один адрес, а когда из конструктора базового класса управление возвращается обратно в конструктор дочернего - уже другой адрес. Архитектура 64 битная, т.е. смещение на 4 байта не объяснить каким-то скрытым указателем, т.к. указателя - 8 байт. Ну и не должна изменятся раскладка в таком случае. Я же не привожу указатель.

На данный момент баг пофиксен, точнее обойден. Если вкратце причиной оказалось то, что была взаимное включение заголовочников. Причем оно жило в коде уже лет несколько, а проблема проявилась только когда я в один из этих заголовочников включил еще один, msgpack.hpp - это проявляло проблему и приводило к неправильной генерации машинного кода. Там еще была ситуация, что при вызове функции передавался указатель, но внутри функции этот указатель также брался со смещением 4 байта и то же приложение сегфолтилось.

Workaround я нашел, копать дальше нет ни желания, ни необходимости. Будем считать что это следствие отсутствия модулей в плюсах.
PM MAIL   Вверх
xvr
Дата 6.8.2018, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 6939
Регистрация: 28.8.2007
Где: Химки, Московская обл

Репутация: 60
Всего: 221



Цитата(drug007 @  5.8.2018,  18:22 Найти цитируемый пост)
Из конструктора дочернего класса вызывается конструктор базового и в конструкторе базового класса мембер имеет один адрес, а когда из конструктора базового класса управление возвращается обратно в конструктор дочернего - уже другой адрес. 

Как вызывали конструктор? Если через ':' - то должно работать, если явно - base(), то это не работает:
Код

class Child: public Base {
  Child() : Base() {}  // Так должно работать
  Child() { Base(); } // Так не будет работать
};


Цитата(drug007 @  5.8.2018,  18:22 Найти цитируемый пост)
 Если вкратце причиной оказалось то, что была взаимное включение заголовочников. Причем оно жило в коде уже лет несколько, а проблема проявилась только когда я в один из этих заголовочников включил еще один, msgpack.hpp - это проявляло проблему и приводило к неправильной генерации машинного кода. 

Очень похоже на залипший объектный файл. Вы поменяли описание класса (в хидере), а какой то объектник не пересобрался (либо зависимостей не хватило, либо были проблемы со временем на компе).
Лечится полной пересборкой проекта

PM MAIL   Вверх
drug007
Дата 6.8.2018, 23:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: нет
Всего: 1



Цитата(xvr @  6.8.2018,  11:08 Найти цитируемый пост)
Как вызывали конструктор? Если через ':' - то должно работать, если явно - base(), то это не работает:

Действительно справедливое замечание, я мог вызвать его явно, но точно сказать не могу, уже дома.

EDIT: проверил код, конструктор вызывался через ':'. В общем я отношу этот баг по прежнему к отсутствию полноценных модулей в языке и наличию такой штуки как модуль трансляции, где воедино мешается код разных авторов, разных годов, разных версий и т.д.

Цитата(xvr @  6.8.2018,  11:08 Найти цитируемый пост)
Очень похоже на залипший объектный файл. Вы поменяли описание класса (в хидере), а какой то объектник не пересобрался (либо зависимостей не хватило, либо были проблемы со временем на компе).
Лечится полной пересборкой проекта

Это вряд ли. Я пересобирал проект чтобы убедится что баг воспроизводится, в том числе откатывался на предыдущий коммит. Да и на сервере проект всегда собирается с нуля как раз чтобы исключить такие ситуации. И локально у меня и на билд сервере ошибка была одна и та же.

Это сообщение отредактировал(а) drug007 - 7.8.2018, 13:46
PM MAIL   Вверх
xvr
Дата 7.8.2018, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 6939
Регистрация: 28.8.2007
Где: Химки, Московская обл

Репутация: 60
Всего: 221



Очень и очень странно. Код не покажете?

PM MAIL   Вверх
drug007
Дата 13.8.2018, 12:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: нет
Всего: 1



Цитата(xvr @  7.8.2018,  14:06 Найти цитируемый пост)
Код не покажете?

Нельзя. Да и не стоит смотреть на этот код  smile 
Это в лучших традициях типичный "энтерпрайз" - многолетний код с кучей легаси, лапши и прочих костылей добавленных чтобы работало и в котором сам черт ногу сломит.
PM MAIL   Вверх
Google
  Дата 22.8.2018, 02:50 (ссылка)  





  Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0937 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.