Можно ли исправить ошибку сегментации Sun Solaris OS 5.8, связанную с int * cast с gcc версии 3.3?

Доброе утро, возможно ли исправить ошибку сегментации Sun Solaris OS 5.8, связанную с int * cast с gcc версии 3.3? Значения переменной GDB показаны ниже. Переменные-члены класса cOrderedList показаны ниже. Uname -a и gcc -v outputa показаны ниже.
Этот код отлично работает на Windows Visual Studio C ++ 9.0. Спасибо.

[Новый LWP 1]

Программа получила сигнал SIGSEGV, Ошибка сегментации.
0xff064b04 в cOrderedList :: LoadDatabaseRecords (cSQLite *, char const *) (
это = 0x68f10, база данных_ = 0xa4ba8,
Command_ = 0xffbed468 "SELECT * FROM LeftPattern")
на ../Source/cOrderedList.cpp:272
272 * ((int *) (Records + RecordCount * RecordSize + FieldOffsets [i])) = База данных _-> ColumnInt (i);
(GDB) печать я
$ 3 = 3
(GDB) печать записей
$ 4 = 0xa0800 "" (gdb) печать RecordCount
$ 5 = 0
(gdb) печать RecordSize
6 долларов = 50
(gdb) печать FieldOffsets [i]
7 долларов США = 46
class cOrderedList {
private:
enum eFieldTypes {
Character,
Integer
};

bool CopyConstructed;

int RecordCount;
int FieldCount;
int RecordSize;

char *Records;
int *FieldSizes,*FieldOffsets;
eFieldTypes *FieldTypes;

char *CurrentPos;
$ uname -a
SunOS 5.8 Generic_108528-22 sun4u sparc SUNW, Sun-Fire-V210

$ gcc -v
Чтение спецификаций из /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/3.3/specs
Настраивается с помощью: ../configure --disable-nls --with-as = / usr / ccs / bin / as --with-ld =
/ USR / к.х.н. / бен / л.д.
Модель потока: posix
bool cOrderedList::LoadDatabaseRecords(cSQLite *Database_,const char *Command_) {
int retVal;
char str[4096];

RetrySQL:
RecordCount=0;
Database_->Prepare(Command_);
while ((retVal=Database_->Step())!=SQLITE_DONE) {
switch (retVal) {
case SQLITE_ROW:
for (int i=0;i<FieldCount;i++) {
if (FieldTypes[i]==Integer) {
*((int*)   (Records+RecordCount*RecordSize+FieldOffsets[i]))=Database_->ColumnInt(i);
} else {
Database_->ColumnText(i,str);
LTrim(str);
RTrim(str);

#if defined(_DEBUG)
if ((int) strlen(str)>=FieldSizes[i])
printf("Field not large enough: %s\n",Command_);
#endif

strncpy(Records+RecordCount*RecordSize+FieldOffsets[i],str,FieldSizes[i]);
Records[RecordCount*RecordSize+FieldOffsets[i]+FieldSizes[i]-1]='\x0';
}
}
RecordCount++;
break;
case SQLITE_BUSY:
continue;
case SQLITE_MISUSE:
goto RetrySQL;
default:
break;
}
}
return true;
}

0

Решение

Добрый день, проблема оказывается не в ошибке генерации кода gcc или переполнении буфера. Следующее решение было протестировано на Solaris несколько минут назад с использованием этого кода:

     int32_t x = Database->ColumnInt(i);
memcpy(Records+RecordCount*RecordSize+FieldOffsets[i], &x, sizeof(int32_t));

Спасибо за все ваши ответы и комментарии.

0

Другие решения

Может быть, эта операция: «(Records + RecordCount * RecordSize + FieldOffsets [i])» возвращает значение, которое превышает размер границ записей.

Трудно сказать, рассматривая только эту часть кода, но это может быть вызвано различием между sizeof (char) на обеих платформах …

0

Немного поздно, но ни один из опубликованных в настоящее время ответов не объясняет, почему отправленный код дает сбой.

Этот код

            *((int*)   (Records+RecordCount*RecordSize+FieldOffsets[i]))=Database_->ColumnInt(i);

нарушает 6.3.2.3. Указатели, пункт 7 стандарта С:

… Указатель на тип объекта может быть преобразован в указатель на другой тип объекта. Если результирующий указатель не правильно выровнен для ссылочного типа, поведение не определено. …

Обратите внимание, что этот код также может нарушать строгое наложение, но я не проанализировал это достаточно близко, чтобы быть уверенным. Дело в том, что Records это char * может учесть псевдоним для int значение. Но даже если код верен при строгом псевдониме, он все равно должен соответствовать всем базовым требованиям к системному выравниванию. int значение, иначе это нарушает ограничения пункта 6.3.2.3 выше.

Не все системы допускают де-факто стандарт х86. Системы SPARC, такие как в этом вопросе, не разрешают такую ​​адресацию «все идет».

0
По вопросам рекламы [email protected]