开发者

LLVM GCC 4.2 EXC_BAD_ACCESS

Below code runs just fine on GCC 4.2 but fails with EXC_BAD_ACCESS in 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;
}
开发者_开发百科

That's how I allocate

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);

Offset and buffer is like

@interface PRDataSet : NSObject {

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

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

}

Yes offset is within range. I do not free the buffer before I use it.

Any ideas?


This could be an aligment problem. The ARM processors (and many other processors) have restrictions regarding the data alignment, e.g. they can only read and write floating-point numbers from addresses that are a multiple of 4 or 8.

From the way the buffer is allocated in your code, it might not be allocated properly, or your double_t data elements aren't aligned within the buffer.

In order to avoid the problem, you should try to first copy the data into an aligned buffer and read it from there.


LLVM just doesn't read float directly.

Here's the solution:

- (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;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜