size_t引发的stack corruption detected

本文记录了一个JNI程序中出现stackcorruptiondetected错误的排查过程,通过更改outlen变量类型从int到size_t解决了由于32位与64位环境下size_t大小不一致引发的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在写JNI程序时,出现了stack corruption detected,刚开始我以为是我分配的内存不够导致越界了,加大内存后依然如此。出现问题的程序如下:

extern "C"
JNIEXPORT jbyteArray JNICALL
Java_net_yiim_yicrypto_NativeSupport__1cipherFinal(JNIEnv *env, jclass type, jlong ptr) {
    unsigned char * buf = (unsigned char *)malloc(sizeof(unsigned char) * 33);
    int outlen = 0;
    if(buf == NULL) {
        YiLog::getInstance().d("cipherFinal alloc memory.");
    }

    int retCode = cipherFinal((void *)ptr, buf + 1, (size_t *)&outlen);
    if(retCode != 0 || outlen < 0) {
        outlen = 1;
    }
    buf[0] = (unsigned char)(retCode & 0x0FF);

    jbyteArray array = env->NewByteArray(outlen + 1);
    env->SetByteArrayRegion(array, 0, outlen + 1, (const jbyte *) buf);

    free(buf);

    return array;
}

异常如下:

--------- beginning of crash
10-11 17:37:56.972 30451 30467 F libc    : stack corruption detected
10-11 17:37:56.973 30451 30467 F libc    : Fatal signal 6 (SIGABRT), code -6 in tid 30467 (roidJUnitRunner)
10-11 17:37:56.974  3019  3019 W         : debuggerd: handling request: pid=30451 uid=10204 gid=10204 tid=30467
10-11 17:37:57.087 30469 30469 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
10-11 17:37:57.088 30469 30469 F DEBUG   : Build fingerprint: 'samsung/zeroltezc/zeroltechn:7.0/NRD90M/G9250ZCU2ERI1:user/release-keys'
10-11 17:37:57.088 30469 30469 F DEBUG   : Revision: '10'
10-11 17:37:57.088 30469 30469 F DEBUG   : ABI: 'arm64'
10-11 17:37:57.089 30469 30469 F DEBUG   : pid: 30451, tid: 30467, name: roidJUnitRunner  >>> net.yiim.yicrypto.android <<<
10-11 17:37:57.089 30469 30469 F DEBUG   : signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
10-11 17:37:57.107 30469 30469 F DEBUG   : Abort message: 'stack corruption detected'
10-11 17:37:57.107 30469 30469 F DEBUG   :     x0   0000000000000000  x1   0000000000007703  x2   0000000000000006  x3   0000000000000008
10-11 17:37:57.107 30469 30469 F DEBUG   :     x4   000000759fa888d0  x5   0080808080808080  x6   0000000000000000  x7   0000000000000010
10-11 17:37:57.107 30469 30469 F DEBUG   :     x8   0000000000000083  x9   ffffffffffffffdf  x10  0000000000000000  x11  0000000000000001
10-11 17:37:57.107 30469 30469 F DEBUG   :     x12  ffffffffffffffff  x13  0000000000000000  x14  0000000000000000  x15  0039fd8c3ba91dfe
10-11 17:37:57.107 30469 30469 F DEBUG   :     x16  00000075b50e3ee0  x17  00000075b508d5ac  x18  00000000ffffffff  x19  00000075a61ff4f8
10-11 17:37:57.108 30469 30469 F DEBUG   :     x20  0000000000000006  x21  00000075a61ff450  x22  0000000000000058  x23  00000075a65e0cad
10-11 17:37:57.108 30469 30469 F DEBUG   :     x24  0000000000000008  x25  63d4f7c6fab6449e  x26  00000075a0940698  x27  63d4f7c6fab6449e
10-11 17:37:57.108 30469 30469 F DEBUG   :     x28  0000000000000002  x29  00000075a61f7740  x30  00000075b508aa54
10-11 17:37:57.108 30469 30469 F DEBUG   :     sp   00000075a61f7720  pc   00000075b508d5b4  pstate 0000000060000000
10-11 17:37:57.114 30469 30469 F DEBUG   : 
10-11 17:37:57.114 30469 30469 F DEBUG   : backtrace:
10-11 17:37:57.114 30469 30469 F DEBUG   :     #00 pc 000000000006b5b4  /system/lib64/libc.so (tgkill+8)
10-11 17:37:57.114 30469 30469 F DEBUG   :     #01 pc 0000000000068a50  /system/lib64/libc.so (pthread_kill+64)
10-11 17:37:57.114 30469 30469 F DEBUG   :     #02 pc 0000000000023f68  /system/lib64/libc.so (raise+24)
10-11 17:37:57.114 30469 30469 F DEBUG   :     #03 pc 000000000001c9ec  /system/lib64/libc.so (abort+52)
10-11 17:37:57.114 30469 30469 F DEBUG   :     #04 pc 0000000000020f74  /system/lib64/libc.so (__libc_fatal+104)
10-11 17:37:57.114 30469 30469 F DEBUG   :     #05 pc 000000000006a498  /system/lib64/libc.so (__stack_chk_fail+16)
10-11 17:37:57.114 30469 30469 F DEBUG   :     #06 pc 0000000000011210  /data/app/net.yiim.yicrypto.android-2/lib/arm64/libyicrypto.so (Java_net_yiim_yicrypto_NativeSupport__1cipherFinal+380)
10-11 17:37:57.115 30469 30469 F DEBUG   :     #07 pc 0000000000236b20  /data/app/net.yiim.yicrypto.android-2/oat/arm64/base.odex (offset 0x219000)

于是在网上各种搜索,百思未得其解,后来不断的打log之后,程序又突然好了,去掉log之后又崩溃。

将JNI编译指定为armeabi-v7a架构,程序运行正常,于是开始怀疑哪里的指针操作有问题,搜索到这篇文章:
stack corruption detected (-fstack-protector)

里面有一个回复是这样的:

4 posts
I've found the problem:

There was a bug like that:

void a(unsigned long* ptr) { *ptr = 0; }

void b() {
 int x;
 a(&x);
}

便想到会不会是size_t在32位及64位环境中,大小不一样导致的,于是把outlen直接定义为size_t后,程序运行正常。
后发现,size_t的定义正是unsigned long,跟上述回复现象一致。

特此,记一坑。

### 函数 `os_thread_create` 的参数详解 以下是函数 `os_thread_create` 中各参数的具体含义: #### 1. **name** - 表示线程的名字,通常是一个字符串形式的标识符。 - 主要用于调试目的,在日志记录或监控工具中可以更容易识别该线程[^1]。 #### 2. **entry** - 这是线程入口函数的指针,即新创建的线程将从这个函数开始执行。 - 类型通常是类似于 `(void *(*)(void *))` 的函数指针,表示接受一个 `void*` 参数并返回 `void*` 值的函数。 #### 3. **param** - 是传递给线程入口函数 (`entry`) 的参数。 - 如果不需要传参,则可以设置为 `NULL` 或其他默认值。 #### 4. **stack_4k_size_num** - 定义线程栈大小,单位是以 4KB 页面的数量来计算。 - 例如,如果希望分配 8 KB 的堆栈空间,则应将此参数设为 2 (因为每页为 4 KB)。 #### 5. **priority** - 设置线程的优先级。 - 数字越低代表优先级越高;具体范围取决于操作系统实现中的定义。 #### 6. **cpu_id** - 指定运行该线程的目标 CPU 编号。 - 可能会采用 `<cpu number>` 形式的配置项,允许开发者指定特定的核心上启动线程。如果没有特殊需求或者系统不支持绑定到某个核心,则可将其留为空白或其他默认选项。 ```c // 示例代码展示如何调用 os_thread_create int thread_stack_pages = 4; // 分配 16K 栈空间 (4 * 4K) const char *thread_name = "exampleThread"; void *thread_param = NULL; uint8_t target_cpu = 0; // 绑定至第一个逻辑处理器 uint8_t thread_priority = 5; os_thread_create(thread_name, example_entry_function, thread_param, thread_stack_pages, thread_priority, target_cpu); ``` 以上是对 `os_thread_create` 所有主要参数的功能描述及其作用场景分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值