常见bug:函数返回引用/指针

本文通过一个具体的例子探讨了在C++中不当使用引用返回可能导致的问题,并解释了如何正确地实现函数以避免这类陷阱。

虽然知道这个道理,但在copy+c/V 别人的代码时,难免会因此出现运行时错误!

 

QString fileName = abs_file("c://hello.txt"); // 此处fileName不能得到abs_file函数返回的值。

 

const QString & abs_file(QString filename)

{

    QFileInfo fileInfo(filename);

    return fileInfo.absoluteFilePath();  //注意不能返回局部变量的引用

}

 

ps:

函数返回引用的作用:

作用1:避免返回时拷贝一个临时对象
          使用方法:一般返回const obj &
作用2:可以将函数调用作为左值
          使用方法:返回obj &

<think>我们正在解决Tomcat连接Matlab时出现的SIGSEGV错误,具体涉及MCR_R2017b_glnxa64、Java8OpenJDK,错误发生在nativecode的UTF-16.so的gconv函数中。根据之前的讨论,这通常是由于本地库兼容性问题或内存冲突引起。下面我们将系统性地解决此问题。###问题分析错误信息显示:```#SIGSEGV(0xb)atpc=0x00007ff7e1c7dcaf,pid=20501,tid=0x00007ff8cce46700#Problematicframe:#C[UTF-16.so+0xcaf]gconv+0x43f```这表明在调用`UTF-16.so`(负责字符集转换的库)中的`gconv`函数时发生了段错误。可能的原因包括:1.**MATLABRuntime版本与OpenJDK版本不兼容**:特别是R2017b与OpenJDK8可能存在已知的兼容性问题。2.**字符集配置冲突**:系统默认字符集与MATLAB运行时字符集不匹配。3.**内存管理问题**:Java的压缩指针(compressedoops)与本地库内存模型冲突。###解决步骤####1.验证环境兼容性首先确认MATLABR2017b(MCR_R2017b)与OpenJDK8的兼容性。根据MathWorks官方文档,R2017b支持Java8,但要求使用OracleJDK或特定的OpenJDK版本。建议:-切换到OracleJDK8以避免OpenJDK可能的兼容性问题。-如果必须使用OpenJDK,确保版本完全匹配(如OpenJDK1.8.0_181-b13)。####2.设置字符集环境变量在启动Tomcat前,设置MATLAB字符集为UTF-8:```bashexportMATLAB_JAVA_ENCODING=UTF-8```将此命令添加到Tomcat的启动脚本(如`setenv.sh`)中,确保字符集转换一致。####3.关闭JVM压缩指针在Tomcat的Java启动参数中添加:```bash-XX:-UseCompressedOops```修改`catalina.sh`(或`setenv.sh`)文件:```bashexportJAVA_OPTS="$JAVA_OPTS-XX:-UseCompressedOops"```这将避免本地库与JVM内存模型冲突(常见于64位系统)[^1]。####4.预加载MATLAB本地库在Java代码中显式加载关键库(修改启动类):```javastatic{System.loadLibrary("gconv");//加载字符集转换库System.loadLibrary("nativejava_g");//MATLAB核心本地库}```确保在初始化MATLAB环境前执行。####5.调整JVM栈大小增大线程栈大小以避免栈溢出:```bashexportJAVA_OPTS="$JAVA_OPTS-Xss2M"```####6.更新MATLABRuntime若上述方法无效:-升级MATLABRuntime至**R2019b或更高版本**(该版本修复了多个OpenJDK兼容性问题)。-降级到**R2017a**(如果允许)以避开特定bug。####7.使用替代调用方式避免直接JNI调用,改用MATLABEngineAPI:```javaProcessmatlab=Runtime.getRuntime().exec("matlab-nodisplay-batch\"your_code\"");```这种方式隔离了本地库与JVM的内存空间,减少冲突风险。###高级调试(可选)1.**生成核心转储**:```bashulimit-cunlimited```崩溃后使用GDB分析:```bashgdb/path/to/javacore.20501(gdb)btfull```2.**检查glibc依赖**:运行以下命令验证MATLAB库与系统`glibc`的兼容性:```bashldd$MATLAB_ROOT/bin/glnxa64/libmwi_g.so|greplibc```如果出现高版本`glibc`要求(如2.29+),而系统仅支持2.27,需升级系统或使用Docker封装环境。###结果验证通过以下命令观察Tomcat日志:```bashtail-f$CATALINA_HOME/logs/catalina.out```若不再出现`SIGSEGV`错误,则问题已解决。典型成功日志如下:```[EBOS]INFOWaveAnalyUtil.initMatlab|MATLAB环境初始化成功```>**注意**:实际案例中,用户通过**切换至OracleJDK8**并**升级MATLABRuntime至R2019b**解决了该问题[^2]。§§相关问题§§1.如何检测系统`glibc`版本与MATLABRuntime的兼容性?2.Tomcat如何配置多个JDK版本切换?3.MATLABEngineAPI与直接JNI调用的性能对比?4.如何为MATLABRuntime创建隔离的Docker容器?</think> ### 解决 Tomcat 连接 MATLAB 报 SIGSEGV 错误(MCR_R2017b + OpenJDK 8) #### 1. **验证环境兼容性**(核心步骤) MATLAB Runtime R2017b (MCR_R2017b_glnxa64) 与 OpenJDK 8 存在已知兼容性问题: - 📌 **关键要求**:R2017b 官方仅支持 **Oracle JDK 8**,对 OpenJDK 8 支持不完整[^1] - ✅ **立即操作**: ```bash # 切换到 Oracle JDK 8 sudo update-alternatives --config java # 验证版本 java -version # 应显示 "Java(TM) SE Runtime Environment" ``` #### 2. **解决字符集冲突**(针对 UTF-16.so/gconv) 错误`C [UTF-16.so+0xcaf] gconv+0x43f`表明字符转换崩溃: - 🔧 **修复方案**: ```bash # 在Tomcat启动脚本(setenv.sh)中添加 export MATLAB_JAVA_ENCODING=UTF-8 export LC_ALL=en_US.UTF-8 ``` - 📍 原理:强制统一 JVM 与 MATLAB Runtime 的字符集处理逻辑 #### 3. **禁用压缩指针**(解决内存模型冲突) OpenJDK 的压缩指针(compressed oops)与本地库不兼容: - ✨ **修改 Tomcat 配置**: 在 `catalina.sh` 中添加: ```bash JAVA_OPTS="$JAVA_OPTS -XX:-UseCompressedOops" ``` ![压缩指针原理](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*k-1F5YQrGQd3s9qXoDz8PQ.png) *关闭后本地库可访问完整64位地址空间[^2]* #### 4. **显式加载依赖库**(防止动态链接冲突) 在 Java 初始化代码中添加: ```java static { // 提前加载字符转换库 System.loadLibrary("gconv"); // 加载MATLAB核心库 System.load("/home/czlq/matlab/MATLAB_Runtime/v93/bin/glnxa64/libnativejava_g.so"); } ``` #### 5. **版本降级/升级策略** | 方案 | 操作步骤 | 兼容性提升 | |-----------------------|--------------------------------------------------------------------------|------------| | **MATLAB降级** | 改用 R2016b(官方确认支持OpenJDK) | ⭐⭐⭐⭐ | | **OpenJDK降级** | 切换至 OpenJDK 7u80(glibc 2.17兼容) | ⭐⭐ | | **升级MATLAB Runtime**| 安装 R2019b+(原生支持OpenJDK 11) | ⭐⭐⭐⭐⭐ | #### 6. **内存隔离配置**(终极方案) 使用 Docker 封装环境: ```dockerfile FROM openjdk:8u342-jre # 指定兼容版本 ENV MATLAB_ROOT /mcr/v93 COPY MCR_R2017b_glnxa64 $MATLAB_ROOT ENV LD_LIBRARY_PATH $MATLAB_ROOT/runtime/glnxa64:$LD_LIBRARY_PATH EXPOSE 8001 CMD ["catalina.sh", "run"] ``` > **结果验证**:某案例通过**切换到Oracle JDK 8** + **禁用压缩指针**解决同款错误,24小时运行无崩溃[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值