#Call segfaults when not inlined

1 messages · Page 1 of 1 (latest)

keen valley
#

Relevant code:

    library: *const anyopaque,
    QSEECom_start_app: T_QSEECom_start_app,
    QSEECom_shutdown_app: T_QSEECom_shutdown_app,
    QSEECom_send_cmd: T_QSEECom_send_cmd,
    QSEECom_send_modified_cmd: T_QSEECom_send_modified_cmd,
    QSEECom_set_bandwidth: T_QSEECom_set_bandwidth,

    pub fn init() !QSEEComAPI {
        const libQSEEComAPI = libc.dlopen("libQSEEComAPI.so", .{ .NOW = true }) orelse {
            return error.FailedToLoadLibrary;
        };

        return QSEEComAPI{
            .io = null,
            .library = libQSEEComAPI,
            .QSEECom_start_app = try core.loadLibrary(libQSEEComAPI, "QSEECom_start_app", T_QSEECom_start_app),
            .QSEECom_shutdown_app = try core.loadLibrary(libQSEEComAPI, "QSEECom_shutdown_app", T_QSEECom_shutdown_app),
            .QSEECom_send_cmd = try core.loadLibrary(libQSEEComAPI, "QSEECom_send_cmd", T_QSEECom_send_cmd),
            .QSEECom_send_modified_cmd = try core.loadLibrary(libQSEEComAPI, "QSEECom_send_modified_cmd", T_QSEECom_send_modified_cmd),
            .QSEECom_set_bandwidth = try core.loadLibrary(libQSEEComAPI, "QSEECom_set_bandwidth", T_QSEECom_set_bandwidth),
        };
    }

pub fn qcomAlign(value: usize) usize {
    const QSEECOM_ALIGN_SIZE: usize = 0x40;
    const QSEECOM_ALIGN_MASK: usize = QSEECOM_ALIGN_SIZE - 1;
    return ((value + QSEECOM_ALIGN_SIZE) & (~QSEECOM_ALIGN_MASK));
}

pub fn loadLibrary(library: ?*anyopaque, symbol: [:0]const u8, Type: type) !Type {
    const address = libc.dlsym(library, symbol) orelse {
        return error.FailedToLoadSymbol;
    };

    return @alignCast(@ptrCast(address));
}

pub fn send(self: *QSEEComAPI, command: ?*anyopaque, commandLength: u32, response: ?*anyopaque, responseLength: u32) c_int {
    return self.QSEECom_send_cmd(self.io, command, commandLength, response, responseLength);
}

pub inline fn sendAlloc(self: *QSEEComAPI, gpa: *const std.mem.Allocator, command: []const u8, requestLength: usize, responseLength: usize) ![]const u8 {
    const request = try gpa.alloc(u8, core.qcomAlign(requestLength));       
    const response = try gpa.alloc(u8, core.qcomAlign(responseLength));
    defer gpa.free(request);

    @memset(response, 0);
    @memset(request, 0);

    @memcpy(request, command);
    
    const result = self.send(request.ptr, request.len, response.ptr, response.len);
    if (result != 0) {
        return error.FailedToSendCommand;
    }

    return response;
}

usage:

const response = try api.sendAlloc(&gpa, &[_]u8{0x01, 0x02}, 0x4000, 8);

works fine as-is, segfaults when removing inline from sendAlloc

zinc wave
#

also, passing a *const Allocator is a bit weird, you should pass the allocator directly

keen valley
#

the platform is an odd one

zinc wave
#

hmmm interesting, that stack trace implies it crashes in malloc

#

there's probably not enough context to debug this i'm afraid; if i'm reading that backtrace correctly it's probably heap corruption, which is Not Fun to debug ^^'

#

idk if you can use valgrind on android? that might help

#

or address sanitizer

keen valley
#

this is android 4/api17 on kernel 3.4 had to resort to using raw_c_allocator since GeneralPurposeAllocator kept giving oom errors and c_allocator doesnt build on a platform this old so theres a decent chance its just a platform quirk