刷新三观的HP-UX系统中的强指针赋值出core问题

简介: 刷新三观的HP-UX系统中的强指针赋值出core问题

      这周在某省升级通信中间件,在RedHat平台的中间件 运行正常,业务可以正常处理。但在 HP-UX服务器上,一承载业务,中间件就出Core重启。


      我立刻组织部门的同事投入到问题分析中。


      首先我在公司的实验室的HP服务器上部署某省的业务。然后在实验室编写votel话务测试脚本,进行业务测试。故障现象浮现,HP下的中间件出core重启。分析代码的位置,是出现在        int i=*(int*)(*begin+1);地方。


       然后对版本进行回滚,原来的代码赋值是


+   int i;


+   memcpy((char*)(&i),(*begin)+1,4);


   将该处代码由强指针转换改为memcpy后,业务中间件正常运行。


  对这个问题百思不得其解,于是我安排小汪在写一个简单的测试程序,代码中只写强制转换的代码。


#include <stdio.h>
int main()
{
char  aa[10] = {'a','b','c','d','d','e','f','a','b','c'};
char *p = (aa+0);
char *p2 = (aa+0); 
char **begin = &p2;
printf("%p\n",*begin);
printf("%p\n",*begin+1);
printf("%p\n",**begin);
int functionID = *(int*)(*begin+1);
printf("functionID=%x\n",functionID);
}


 用aCC编译后,运行程序,果然出core。

然后改用代码


#include <stdio.h>
int main()
{
char  aa[10] = {'a','b','c','d','d','e','f','a','b','c'};
char *p = (aa+0);
char *p2 = (aa+0); 
char **begin = &p2;
printf("%p\n",*begin);
printf("%p\n",*begin+1);
printf("%p\n",**begin);
int functionID ;
memcpy((char*)&functionID,(*begin)+1,4);
printf("functionID=%x\n",functionID);
}


aCC编译后运行正常。


小汪跟我说他看到一个帖子,挺有借鉴意义的,具体如下:


7af869d9170249dbb9eea0112f3f01ef.png


概括来讲有的CPU存在内存奇偶的机制,要用偶数内存地址做强制转换。


于是我按照这个文章讲的,对代码又做了修改验证:


#include <stdio.h>
int main()
{
char  aa[10] = {'a','b','c','d','d','e','f','a','b','c'};
char *p = (aa+0);
char *p2 = (aa+0); 
char **begin = &p2;
printf("%p\n",*begin);
printf("%p\n",*begin+1);
printf("%p\n",**begin);
int functionID = *(int*)(*begin+2);
printf("functionID=%x\n",functionID);
}


经过aCC编译验证后,程序仍然出core。


然后我接着进行了修改,具体如下:


#include <stdio.h>
int main()
{
char  aa[10] = {'a','b','c','d','d','e','f','a','b','c'};
char *p = (aa+0);
char *p2 = (aa+0); 
char **begin = &p2;
printf("%p\n",*begin);
printf("%p\n",*begin+1);
printf("%p\n",**begin);
int functionID = *(int*)(*begin+4);
printf("functionID=%x\n",functionID);
}


对于指针地址+4后,进行强制转换,用aCC编译后运行,程序可以正常运行。


然后我把情况给小汪讲了后,小汪又做了个测试:


#include <stdio.h>
int main()
{
char  aa[10] = {'a','b','c','d','d','e','f','a','b','c'};
char *p = (aa+0);
char *p2 = (aa+0); 
char **begin = &p2;
printf("%p\n",*begin);
printf("%p\n",*begin+1);
printf("%p\n",**begin);
int functionID = *(short*)(*begin+2);
printf("functionID=%x\n",functionID);
}


用aCC编译后,程序也可以正常运行。


总结下:


进行数值进行强转赋值需要谨慎,有的CPU存在内存对齐和起始地址的奇偶性。所以尽量用memcpy(类似memcpy((char*)(&i),(*begin)+1,4);),少用类型强转赋值(类似int i=*(int*)(*begin+1);)。

相关文章
|
2月前
|
算法 Linux C语言
【Linux系统编程】深入理解Linux目录操作:文件夹位置指针操作函数(telldir,seekdir,rewinddir)
【Linux系统编程】深入理解Linux目录操作:文件夹位置指针操作函数(telldir,seekdir,rewinddir)
44 0
|
14天前
|
搜索推荐 程序员 C语言
指针赋值与引用传递:C语言的基础知识与实践技巧
指针赋值与引用传递:C语言的基础知识与实践技巧
|
13天前
|
搜索推荐 程序员 C语言
指针赋值与引用传递:C语言的基础知识与实践技巧
指针赋值与引用传递:C语言的基础知识与实践技巧
|
2月前
|
机器学习/深度学习 计算机视觉
LabVIEW开发自动读取指针式仪表测试系统
LabVIEW开发自动读取指针式仪表测试系统
37 7
|
2月前
|
设计模式 安全 Java
【Linux 系统】多线程(生产者消费者模型、线程池、STL+智能指针与线程安全、读者写者问题)-- 详解
【Linux 系统】多线程(生产者消费者模型、线程池、STL+智能指针与线程安全、读者写者问题)-- 详解
|
9月前
|
存储 Linux 编译器
Linux系统中指针的详细分析与操作
Linux系统中指针的详细分析与操作
85 1
|
9月前
|
JSON 数据格式 存储
No.12 gin框架中的binding究竟是干嘛的?(二)
No.12 gin框架中的binding究竟是干嘛的?
No.12 gin框架中的binding究竟是干嘛的?(二)
|
9月前
|
Go
No.19 干!系统崩溃,又空指针panic?(三)
No.19 干!系统崩溃,又空指针panic?
|
9月前
|
安全 Go
No.19 干!系统崩溃,又空指针panic?(二)
No.19 干!系统崩溃,又空指针panic?
|
9月前
|
存储 Go
No.19 干!系统崩溃,又空指针panic?(一)
No.19 干!系统崩溃,又空指针panic?