LLVM GCC 4.2 EXC_BAD_ACCESS - PullRequest
0 голосов
/ 20 мая 2011

Ниже код прекрасно работает на GCC 4.2, но завершается ошибкой с EXC_BAD_ACCESS в LLVM GCC 4.2

- (double_t)readDouble  {
    double_t *dt = (double_t *)(buffer+offset);
    double_t ret = *dt; // Program received signal: EXC_BAD_ACCESS
    offset += 8;
    return ret;
}

Вот как я распределяю

int dataLength = [data length];
buffer = malloc(dataLength + 1);
buffer[dataLength] = 0; // null terminate to log
[data getBytes:(void *)buffer length:[data length]];
//NSLog(@"%s", buffer);

Смещение и буфер как

@interface PRDataSet : NSObject {

    NSMutableArray *tables;
    NSMutableDictionary *tablesByName;
    NSMutableDictionary *tablesById;

@private
    NSURLConnection *conn;
    int offset;
    char *buffer;

}

Да, смещение находится в пределах диапазона. Я не освобождаю буфер перед использованием.

Есть идеи?

Ответы [ 2 ]

2 голосов
/ 20 мая 2011

Это может быть проблемой aligment. Процессоры ARM (и многие другие процессоры) имеют ограничения относительно выравнивания данных, например, они могут только читать и записывать числа с плавающей запятой с адресов, кратных 4 или 8.

Из-за того, как буфер выделен в вашем коде, он может быть размещен неправильно, или ваши double_t элементы данных не выровнены в буфере.

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

1 голос
/ 21 мая 2011

LLVM просто не читает float напрямую.

Вот решение:

- (uint32_t)readUInt32  {
    uint32_t ret = *(uint32_t *)(buffer+offset);
    offset += 4;
    return ret;
}

- (uint16_t)readUInt16  {
    uint16_t ret = *(uint16_t *)(buffer+offset);
    offset += 2;
    return ret;
}

- (uint64_t)readUInt64  {
    uint64_t ret = *(uint64_t *)(buffer+offset);
    offset += 8;
    return ret;
}

- (float_t)readSingle  {
    uint32_t t = [self readUInt32];
    float_t ret = *((float_t *)(&t));
    return ret;
}

- (double_t)readDouble  {
    uint64_t t = [self readUInt64];
    double_t ret = *((double_t *)(&t));
    return ret;
}
...