调用LoadLibrary时抛出std::bad_alloc错误,求原因分析
问题描述
我尝试加载一款使用Android NDK构建、带有JNI桥接的so库,以便在Kotlin中调用。但调用System.loadLibrary("shared_librar.so")时,出现了如下错误,且我还未实际调用该库中的任何功能:
> Task :test FAILED terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':test'. > Process 'Gradle Test Executor 25' finished with non-zero exit value 134 This problem might be caused by incorrect test process configuration. Please refer to the test execution section in the User Manual at https://docs.gradle.org/7.5.1/userguide/java_testing.html#sec:test_execution * Try: > Run with --info or --debug option to get more log output. > Run with --scan to get full insights. * Exception is: org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':test'. at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:142) at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:282) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:140) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:128) at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:77) at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46) at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51) at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57) at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56) at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52) at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204) at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199) at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66) at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59) at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157) at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59) at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53) at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52) at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:69) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:327) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:314) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:307) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:293) at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:420) at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:342) at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64) at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48) Caused by: org.gradle.process.internal.ExecException: Process 'Gradle Test Executor 25' finished with non-zero exit value 134 This problem might be caused by incorrect test process configuration. Please refer to the test execution section in the User Manual at https://docs.gradle.org/7.5.1/userguide/java_testing.html#sec:test_execution at org.gradle.api.internal.tasks.testing.worker.ForkingTestClassProcessor.stop(ForkingTestClassProcessor.java:192) at org.gradle.api.internal.tasks.testing.processors.RestartEveryNTestClassProcessor.endBatch(RestartEveryNTestClassProcessor.java:77) at org.gradle.api.internal.tasks.testing.processors.RestartEveryNTestClassProcessor.stop(RestartEveryNTestClassProcessor.java:62) at jdk.internal.reflect.GeneratedMethodAccessor756.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) at org.gradle.internal.dispatch.FailureHandlingDispatch.dispatch(FailureHandlingDispatch.java:30) at org.gradle.internal.dispatch.AsyncDispatch.dispatchMessages(AsyncDispatch.java:87) at org.gradle.internal.dispatch.AsyncDispatch.access$000(AsyncDispatch.java:36) at org.gradle.internal.dispatch.AsyncDispatch$1.run(AsyncDispatch.java:71) at org.gradle.internal.concurrent.InterruptibleRunnable.run(InterruptibleRunnable.java:42) at org.gradle.internal.operations.CurrentBuildOperationPreservingRunnable.run(CurrentBuildOperationPreservingRunnable.java:42) at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64) at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48) * Get more help at https://help.gradle.org BUILD FAILED in 4s 5 actionable tasks: 1 executed, 4 up-to-date
原因分析与解决方案
出现std::bad_alloc但未调用库功能,说明崩溃发生在SO库的加载阶段,而非函数调用阶段,常见原因及排查方向如下:
1. SO库的静态初始化代码存在内存分配错误
C/C++的全局变量、静态对象会在SO库被加载时自动执行初始化逻辑,如果这段代码中存在以下情况,会直接抛出std::bad_alloc:
- 尝试分配超出系统/进程可用内存的大块内存(比如
new int[1024*1024*1024]) - 内存分配逻辑存在错误(比如无限循环申请内存)
- 依赖的内存资源未正确初始化,导致分配失败
排查建议:
- 检查SO库中全局变量、静态对象的初始化代码,定位不合理的内存申请逻辑
- 在NDK代码中添加日志,跟踪初始化阶段的内存分配情况
2. 架构不匹配
你构建的SO库的CPU架构(如arm64-v8a、armeabi-v7a)与测试环境的架构不兼容,比如在x86/x86_64的模拟器或测试机上加载arm架构的SO,会导致内存访问异常,间接触发std::bad_alloc类错误。
排查建议:
- 查看测试设备的CPU架构(Android设备可通过
adb shell getprop ro.product.cpu.abi获取) - 确认NDK构建脚本中指定的ABI与测试设备架构一致
3. 依赖库缺失或版本不兼容
SO库依赖的系统库或第三方库在测试环境中不存在,或者版本不匹配,会导致加载时的内存初始化异常,进而抛出std::bad_alloc。
排查建议:
- 使用
readelf -d libshared_librar.so查看SO库的依赖项 - 检查测试环境中是否存在所有依赖库,且版本符合要求
4. 测试进程内存限制不足
Gradle测试进程的内存配额太小,SO库加载时初始化需要的内存超过了进程可用额度,导致内存分配失败。
排查建议:
- 在模块的
build.gradle中调整测试进程的JVM参数,增大堆内存:
test { jvmArgs '-Xmx2048m' }
内容的提问来源于stack exchange,提问作者mconte
相关产品推荐
相关产品推荐

