Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: наложение в памяти. Чей глюк ?  (Прочитано 14194 раз)
0 Пользователей и 3 Гостей смотрят эту тему.
DneprSMV
Помогающий

kz
Offline Offline
Пол: Мужской

« : 05-10-2011 07:58 » 

Имеется проект VC6, wizard-Dialog, MFC, компиляция "Debug"
Затирается переменная в классе Dialog.
(вылечилось установкой опций компилятора выравнивания на 1 байт. Но это устранение последствий,
причину понять не могу. Отладчик слабоват по информативности-не дает физ.адресов , начал уже просматривать листинги на asm)
Кто глючит, я или компилятор ?  Как отловить супостата ?
-------
После долгих процедур с отладчиком, лог. поиском, установкой отладочных if(1) return(1)
и методов "половинного деления" источник затирания нашелся.
Это работа класса, входящего public в Dialog.
при работе   MyClass::cMc.parse() меняется Dialg::f_arch    (!)
Код: (C++)
class Dialog : public CDialog {
.....
public:
  MyClass cMc;    // конструктор-деструктор пустые.
  int f_arch;
}
 
при работе MyClass::cMc.parse():
Код: (C++)
MyClass::parce(...) {
. . . .
  n_elem = 0;  //  <--- оно меняет Dialg::f_arch  (вместо 0 подставлял различные значения)
. . . .
}

Может из-за динамического выделения памяти ?
Помогите советом, долбусь уже 2 дня  Жаль
« Последнее редактирование: 05-10-2011 15:47 от Вад » Записан

"Не слушайте никаких советов, в том числе и этот" (Сократ ?)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 05-10-2011 08:52 » 

DneprSMV, мало кода. Может n_elem - ссылка на f_arch. Тогда, конечно, это одна и та же область памяти.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
DneprSMV
Помогающий

kz
Offline Offline
Пол: Мужской

« Ответ #2 : 05-10-2011 11:14 » 

DneprSMV, мало кода. Может n_elem - ссылка на f_arch. Тогда, конечно, это одна и та же область памяти.
да, извиняюсь, не все привел по MyClass. Переменные банальные int.
никаких ссылок, указателей, в том числе "забытых" нет.
memset() - отключал, там все корректно. Глюк остался.
Еслиб было оно, то ошибка не пропадала бы при другой опции компилятора.
Тут понятно было бы, руки-мозг кривые  Улыбаюсь
Кода много (более 150к), весь свой, те ориентируюсь (мне так кажется, по крайней мере Улыбаюсь
Код: (C++)
class Dialog : public CDialog {
.....
public:
  MyClass cMc;    // конструктор-деструктор пустые.
  int f_arch;
}

class MyClass {
.....
public:
  int n_elem;
 . . .
  SPT_parser(void );
  ~SPT_parser(void) {};
}
----------- Возможный глюк. --------------
при работе MyClass::cMc.parse() оператор (n_elem = 12345) затирает (int f_arch)
------------------------------------------
Код: (C++)
MyClass::parce(...) {
. . . .
  n_elem = 0;  //  <--- оно меняет Dialg::f_arch  (вместо 0 подставлял различные значения)
. . . .
}
Зацепка та, что при включении выравнивания=1 начинает работать корректно.
Видимо придется отсаживать в песочницу и мучить там. Но где гарантия, что глюк не исчезнет при уменьшении размера кода ?

Добавлено через 9 минут и 11 секунд:
ps - ошибся однако опять.
---------
  SPT_parser(void );
  ~SPT_parser(void) {};
---------
читать как
  MyClass(void );    // тут есть иницаиализация данных     MyClass::MyClass() {. . . .}
  ~MyClass(void) {};
« Последнее редактирование: 05-10-2011 11:24 от DneprSMV » Записан

"Не слушайте никаких советов, в том числе и этот" (Сократ ?)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 05-10-2011 12:30 » 

DneprSMV, диспетчер памяти стандартный или самописный?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
DneprSMV
Помогающий

kz
Offline Offline
Пол: Мужской

« Ответ #4 : 05-10-2011 13:32 » 

DneprSMV, диспетчер памяти стандартный или самописный?
все родное, стандартное.
Вот распечатал ptr на одно и на второе.
Когда включено выравнивание по умолчанию(8) - 0012FDCC  и 0012FDCD (1 байт для Int маловатобудет)
Когда включено выравнивание             (1) - 0012FDC9  и 0012FDCD (накладки нет, смещ. 4 байта)
Вот и доверяй компилерам. Это заметил чисто случайно.
используются pragma pack(1) активно по структурам, может из-за них ?
Хотя компилятор вроде должен разруливать.

Добавлено через 2 минуты и 9 секунд:
не привык еще к синтаксису форума, звиняйте.
Вместо смайлика вверху было (8) - выравнивание.
« Последнее редактирование: 05-10-2011 13:34 от DneprSMV » Записан

"Не слушайте никаких советов, в том числе и этот" (Сократ ?)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 05-10-2011 15:48 » 

Цитата: DneprSMV
используются pragma pack(1) активно по структурам, может из-за них ?
Не должно бы. Ведь размер int - 4, т.е. вне зависимости от pragma pack должен выделять как минимум 4 байта.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
DneprSMV
Помогающий

kz
Offline Offline
Пол: Мужской

« Ответ #6 : 05-10-2011 16:59 » 

тоже думаю, что не должно. Ведь компиляторы для того и выдуманы, чтоб не считать границы-смещения вручную. А тут получился явный нахлест 3 байта.
Спасибо за ответ  Улыбаюсь
Пока "забодаю последствия", а попосле надо будет попробовать тотже исходник компиляторе поновее. Времени жаль, тем более "деблохер" скуповат на возможности Жаль
 
Записан

"Не слушайте никаких советов, в том числе и этот" (Сократ ?)
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 05-10-2011 17:07 » 

DneprSMV, не надо валить на компилятор - VC6 многие пользовались и пользуются. Лучше сделай копию своего исходника, удали оттуда все "лишнее" и выложи здесь. НО, сперва ты его сам скомпилируй и проверь, что проблема сохранилась.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
DneprSMV
Помогающий

kz
Offline Offline
Пол: Мужской

« Ответ #8 : 05-10-2011 17:44 » new

RXL
Хорошо, если так, и глюки-плюхи мои. Но сейчас времени нет, и так 2 дня угробил на отлов.
Как раз и хотел услышать здесь, что нет явных ругательств в сторону VC6 по этой тематике.
(хотя думаю по warning должно было чтонить подсказать).
Ужать исходник для отлова попробую, - главное "плюху" не спугнуть. Придется урезать опятьже методом половинного деления  Улыбаюсь
Как забодаю, инф. выложу, если кому интересно.
Может сборка VC6 неудачная ID=83903-873-2478824-78035 ?
Записан

"Не слушайте никаких советов, в том числе и этот" (Сократ ?)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #9 : 05-10-2011 21:25 » 

DneprSMV, ищи по проекту "#pragma" , из них обращай внимание на "#pragma pack" . Результаты в студию )

Добавлено через 1 минуту и 57 секунд:
ага, сразу не увидел - ты пишешь как раз об этом. Правильно пользоваться так:

Код:
#pragma pack(push,1)
...
...
#pragma pack(pop)

таким образом не нарушишь выравнивание вне этих "скобок"

Добавлено через 4 минуты и 10 секунд:
Цитата: DneprSMV
используются pragma pack(1) активно по структурам, может из-за них ?
Не должно бы. Ведь размер int - 4, т.е. вне зависимости от pragma pack должен выделять как минимум 4 байта.

он пользуется паком так, что проблема может появиться. Я как-то натыкался )) Я тогда пропустил по невнимательности и не вписал восстановление выравнивания. После этого одна из функций стала дурачится - принимаемый аргумент внутри функции был другого размера, тем самым сдвигая стек и поганя другие аргументы. Хитрое проявление было - и точно из-за этого
« Последнее редактирование: 05-10-2011 21:31 от Алексей1153 » Записан

DneprSMV
Помогающий

kz
Offline Offline
Пол: Мужской

« Ответ #10 : 06-10-2011 06:42 » 

Алексей1153++
Спасиб за инф. "Меня терзали смутные сомненья ....", но были бооольшие надежды
на компилятор. Пока поставил в свойствах проекта опцию на выравнивание = 1. Помогло.
Проект с глючком запаковал, как освобожусь, погоняю дальше.
Вообще моглож warn выдать (листинг по максимуму опция). Пересмотрел листинг - никакого намека Жаль
Это я после прогонов компилятора должен еще прогонять текст факт. вручную  Улыбаюсь
Хотя мож чевой и пропустил.
Записан

"Не слушайте никаких советов, в том числе и этот" (Сократ ?)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #11 : 06-10-2011 10:57 » 

Вообще моглож warn выдать

нет, зачем ему выдавать предупреждение ? Человек захотел выравнивание 1 , а обратно переключить не захотел. В итоге может получится интересная ситуация :

 к примеру, в файле 111.h у тебя некорректно переключилось выравнивание в 1 - и не вернулось обратно.
а в ыайле 222.h определён класс C222

 в двух файлах реализации идут по два инклуда:

Код:
1.cpp:
#include "111.h" // переключилось выравнивание -> 1
#include "222.h" //сюда применилось выравнивание 1


2.cpp:
#include "222.h"//сюда применилось выравнивание по умолчанию - 4

в итоге: в файле 1.cpp  экземпляры класса C222 имеют выравнивание 1, а в 2.cpp - 4.
Собственно, осталось из файла 1.cpp вызвать метод класса C222 у объекта, объявленного в файле 2.cpp - и схлопотать ошибку
Записан

DneprSMV
Помогающий

kz
Offline Offline
Пол: Мужской

« Ответ #12 : 06-10-2011 12:49 » 

Алексей1153++
Вот за эту идею спасибо ! Программа собирается из более 4 модулей, может быть нестыковка.
Я както этому не сильно внимания уделял. Компилятору пока амнистия, ну и слава богу.
Действительно, прагмой мы принудительно изменяем режим компиляции. Соответственно сам изменил - сам и должен отследить "в трезвом уме и здравом рассудке".
Освобожусь обязательно проверю. 
Еще раз гранд спасиб !


Добавлено через 3 дня, 5 часов, 40 минут и 53 секунды:
Алексей1153++,
1. пересмотрел исходники напредмет использования #pragma pack(1)
ко великому стыду, push-pop не использовал. (ПО перегонялось из QNX - WC и собиралось из модулей.
плюха там или не проявлялась или не была замечена. Может и опции компилятра помогали, скорее всего выравнивалось все 1 байт).

2. проверил, добавил push-pop.  Это ОНО и было - из-за области действия pack()
Правда отловить цепочку, где именно перекрывает, сложно - есть перекрестные объявления в классах
- придется отслеживать #ifndef - #define, как включаются хедеры, в какой последовательности.
Думаю на этом вопрос закрыть, тк причина понятна.

3. Если в двух словах, в одном модуле, с одним выравниваением размер объекта class ssocket
может быть не равен такому же объекту в другом модуле, с другой опцией выравнивания или умолчанием.
(хотя может и совпасть, тут уж лотерея). А может быть и "четная ошибка". Размер один, а внутри разнобой.


// ======= ssocket.hpp ===========
#ifndef __SSOCKET_H_
#define __SSOCKET_H_
#include <sys\types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#pragma comment (lib,"ws2_32.lib")

typedef int my_int1;
typedef int  size_tt; // for TCP.4 lib

// =================
#pragma pack(push,1)     <<<<<<<<<< так надо, это правильно  (NEW)
//#pragma pack(1)        <<<<<<<<<< так НЭ надо  Улыбаюсь  (old-error)

class ssocket
{
. . . .
};
#pragma pack(pop)     <<<<<<<<<< так надо, это правильно  (NEW)

#endif // SSOCKET_H


Алексей1153++, Спасибо.
Весь исходник не выкладываю, тк. много, да и все понятно, я думаю.



« Последнее редактирование: 09-10-2011 18:29 от DneprSMV » Записан

"Не слушайте никаких советов, в том числе и этот" (Сократ ?)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 10-10-2011 06:00 » 

DneprSMV, если есть возможность править код обоих сторон - и сервера, и клиента, подумай о том, чтобы совсем убрать выравнивание у обоих (вернее, оставить по умолчанию - 4).

 Или ТОЧНО тут есть какие-то причины делать выравнивание ?
Записан

DneprSMV
Помогающий

kz
Offline Offline
Пол: Мужской

« Ответ #14 : 10-10-2011 06:40 » 

Алексей1153++,
Нет, без выравнивания не обойтись, или придется существенно перписывать 2 класа - сокетов и пакет-сериал. Программа удаленного доступа к теплосчетчику, реализует его протокол обмена.
"Пакет" счетчика который передается (клиент(Win)-UDP-сервер(QNX)-порт/dev/ser1-счетчик), набирается из структур через ф-ии вроде memcpy(req_TxPacket.buf, hdr1, len);
поэтому для данного постороения без выравнивания на 1 по структурам никак.
Кроме того система "расползлась" на Win - клиент и QNX (сервер).
Если переделывать, то лучше я думаю, не "менять" а прописать все с нуля.
Много чего сейчас сделал бы по-другому  Улыбаюсь
Проект уже в эксплуатации 2 года (все на QNX), а недавно потребовалось сделать клиента (монитор) под Win.



Записан

"Не слушайте никаких советов, в том числе и этот" (Сократ ?)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #15 : 10-10-2011 06:55 » 

ну да, если нужно поддерживать старьё - то лучше не трогать.

Записан

DneprSMV
Помогающий

kz
Offline Offline
Пол: Мужской

« Ответ #16 : 10-10-2011 14:23 » 

Алексей1153++,
я тоже так думаю.
Как освоюсь нормально в Win - переписать, и проделать обратный процесс -
перегнать в сторону QNX. (когда переносил на Win - как не странно - проблем практически небыло)
---------
Всем спасибо.
Вопрос закрыт ..... пока   Улыбаюсь
« Последнее редактирование: 10-10-2011 14:26 от DneprSMV » Записан

"Не слушайте никаких советов, в том числе и этот" (Сократ ?)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines