Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > Раскладка мемберов в дочерней структуре |
Автор: drug007 1.8.2018, 11:11 |
Всем привет! Работаю над старым проектом с кучей легаси. В процессе рефакторинга перестал работать код, который не менялся и работает уже несколько лет. Выяснилось, что в базовой структуре поле инициализируется как положено, а в дочерней структуре это же поле имеет адрес со смещением 4 байта относительно адреса в базовой структуре и соответственно при первой же записи в это поле происходит повреждение памяти с дальнейшим сегфолтом. Ошибка наблюдается под gcc 4.7.2 и gcc 6.3.0. Куда копать пока не знаю, может кто что подскажет? |
Автор: drug007 1.8.2018, 12:35 |
По всей видимости проблемы в том, что кто-то портит память, так как изменил порядок членов структуры и сегфолт в совершенно другом месте. Поздравляю себя с увлекательнейшей отладкой на ближайшее время... |
Автор: drug007 5.8.2018, 18:22 |
Спасибо что ответили! Я не совсем ясно выразился. Из конструктора дочернего класса вызывается конструктор базового и в конструкторе базового класса мембер имеет один адрес, а когда из конструктора базового класса управление возвращается обратно в конструктор дочернего - уже другой адрес. Архитектура 64 битная, т.е. смещение на 4 байта не объяснить каким-то скрытым указателем, т.к. указателя - 8 байт. Ну и не должна изменятся раскладка в таком случае. Я же не привожу указатель. На данный момент баг пофиксен, точнее обойден. Если вкратце причиной оказалось то, что была взаимное включение заголовочников. Причем оно жило в коде уже лет несколько, а проблема проявилась только когда я в один из этих заголовочников включил еще один, msgpack.hpp - это проявляло проблему и приводило к неправильной генерации машинного кода. Там еще была ситуация, что при вызове функции передавался указатель, но внутри функции этот указатель также брался со смещением 4 байта и то же приложение сегфолтилось. Workaround я нашел, копать дальше нет ни желания, ни необходимости. Будем считать что это следствие отсутствия модулей в плюсах. |
Автор: xvr 6.8.2018, 11:08 | ||||||
Как вызывали конструктор? Если через ':' - то должно работать, если явно - base(), то это не работает:
Очень похоже на залипший объектный файл. Вы поменяли описание класса (в хидере), а какой то объектник не пересобрался (либо зависимостей не хватило, либо были проблемы со временем на компе). Лечится полной пересборкой проекта |
Автор: drug007 6.8.2018, 23:12 | ||||
Действительно справедливое замечание, я мог вызвать его явно, но точно сказать не могу, уже дома. EDIT: проверил код, конструктор вызывался через ':'. В общем я отношу этот баг по прежнему к отсутствию полноценных модулей в языке и наличию такой штуки как модуль трансляции, где воедино мешается код разных авторов, разных годов, разных версий и т.д.
Это вряд ли. Я пересобирал проект чтобы убедится что баг воспроизводится, в том числе откатывался на предыдущий коммит. Да и на сервере проект всегда собирается с нуля как раз чтобы исключить такие ситуации. И локально у меня и на билд сервере ошибка была одна и та же. |
Автор: xvr 7.8.2018, 14:06 |
Очень и очень странно. Код не покажете? |
Автор: drug007 13.8.2018, 12:43 |
Нельзя. Да и не стоит смотреть на этот код Это в лучших традициях типичный "энтерпрайз" - многолетний код с кучей легаси, лапши и прочих костылей добавленных чтобы работало и в котором сам черт ногу сломит. |