64位机器,段错误,struct地址返回被截断成32位问题

[复制链接]
查看11 | 回复4 | 2021-1-27 06:25:47 | 显示全部楼层 |阅读模式
操作系统:redhat6.564bit
Linuxip-172-31-20-108.ap-northeast-1.compute.internal2.6.32-431.11.2.el6.x
86_64#1SMPMonMar313:32:45EST2014x86_64x86_64x86_64GNU/Linux
代码片段:
#0
structtask_struct{
U32id;
U32seq;
U32cmd;
intin_len;
intmem_len;
intout_len;
intfunc;
intmode;
intsock;
pthread_spinlock_t*wr_lock;
chariv[KEY_LENGTH];
charkm0_ks[256];
char*in_data;
char*out_data;
structtask_struct*next;
structtask_struct*pre;
};
#1
structtask_struct*get_idle_task(structtask_pool_struct*pool){
structtask_struct*task=0;
if(pool){
pthread_spin_lock(&pool->lock);
if(pool->list_head.next!=&pool->list_head){
task=pool->list_head.next;
rm_task_from_list(task);
pool->count--;
}
pthread_spin_unlock(&pool->lock);
}
if(!task){
task=malloc(sizeof(*task));
}
if(task)
memset(task,0,sizeof(*task));
returntask;
}
#2
intread_ab_file(char*fn,char**bufptr)
{
intrc=0;
intenclen;
charfulfn[128];
char*buf=0;
char*encbuf=0;
FILE*f;
structtask_struct*tmptask;
structtask_struct*task;
memset(fulfn,0,128);
FileName(fn,fulfn,128);
//printf("willreadfile:%s\n",fulfn);
f=fopen(fulfn,"rb");
if(!f)return-1;
fseek(f,0,SEEK_END);
enclen=ftell(f);
intkey_index;
intid=time(NULL);
intseq=rand();
adstr_upr(fulfn);
key_index=GetKeyIndex(fulfn,"");
if(enclen>0&&!(enclen&0xf))
{
task=get_idle_task(0);
if(!task){
fclose(f);
printf("getidletaskfail...\n");
return-1;
}
#############################
task->cmd=BINDATA_DEC;《=====这个地方,段错误
task->id=id;
task->seq=seq;
task->mode=CBC;
task->func=DEC;
###
编译命令:
gcc-g-c-w-fpic-D__LINUX__-DXXXXXX-D_DEBUG-D__FILE_OFFSET_BITS=64-D__USE_FILE_OFFSET64
#########################################
gdb调试:
#### 在get_idle_task 函数内,返回前task地址为:0x7f1340000b70
(gdb)ptask
$15=(structtask_struct*)0x7f1340000b70
(gdb)s
428}
。。。
。。。
###在get_idle_task返回后,task地址为0x40000b70
41if(!task){
(gdb)s
46task->cmd=BINDATA_DEC;
(gdb)ptask
$16=(structtask_struct*)0x40000b70
(gdb)p*task
Cannotaccessmemoryataddress0x40000b70
(gdb)
###task地址在get_idle_task函数内为0x7f1340000b70,get_idle_task返回后为0x40000b70
变短了,是编译选项的问题?如何解决?什么原因导致的
求解答,谢谢

分 -->
回复

使用道具 举报

千问 | 2021-1-27 06:25:47 | 显示全部楼层
这行task=get_idle_task(0);之后,task->cmd=BINDATA_DEC;这行之前有没有其他代码?
如果有的话看看有没有修改task的可能。
ps:用valgrind跟踪一下应该能看出一些问题。
回复

使用道具 举报

千问 | 2021-1-27 06:25:47 | 显示全部楼层
看起来挺诡异的,是每次必现吗?
回复

使用道具 举报

千问 | 2021-1-27 06:25:47 | 显示全部楼层
从行号上看:
get_idle_task函数定义位于400多行,
read_ab_file函数位于40多行
在文件的开头加上get_idle_task函数的声明应该能解决问题。

structtask_struct*get_idle_task(structtask_pool_struct*pool);

回复

使用道具 举报

千问 | 2021-1-27 06:25:47 | 显示全部楼层
应该是缺少了函数get_idle_task()的声明.
这个问题中,64位下,调用get_idle_task()后,编译器把函数的返回值看成了默认的int类型,于是只截出了其中32bit出来(但地址是64位的).而在32位下,地址也是32位,被当成整型时,赋值过程没有截断,所以表面上没有发生问题。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行