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

dodevtest 2014-12-26 11:53:58
操作系统:redhat6.5 64bit

Linux ip-172-31-20-108.ap-northeast-1.compute.internal 2.6.32-431.11.2.el6.x
86_64 #1 SMP Mon Mar 3 13:32:45 EST 2014 x86_64 x86_64 x86_64 GNU/Linux

代码片段:

#0
struct task_struct{
U32 id;
U32 seq;
U32 cmd;
int in_len;
int mem_len;
int out_len;
int func;
int mode;
int sock;
pthread_spinlock_t* wr_lock;
char iv[KEY_LENGTH];
char km0_ks[256];
char* in_data;
char* out_data;
struct task_struct* next;
struct task_struct* pre;
};

#1

struct task_struct* get_idle_task(struct task_pool_struct* pool){
struct task_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));
return task;

}

#2

int read_ab_file( char * fn , char ** bufptr )
{

int rc = 0 ;
int enclen ;
char fulfn[128] ;
char * buf = 0 ;
char * encbuf = 0 ;
FILE * f ;
struct task_struct* tmptask;
struct task_struct* task;
memset(fulfn,0,128);
FileName ( fn , fulfn , 128 ) ;
//printf("will read file:%s\n",fulfn);
f = fopen ( fulfn , "rb" ) ;
if ( !f ) return -1 ;
fseek ( f , 0 , SEEK_END ) ;
enclen = ftell ( f ) ;
int key_index;
int id=time(NULL);
int seq=rand();
adstr_upr(fulfn);
key_index=GetKeyIndex(fulfn,"");
if ( enclen > 0 && !(enclen&0xf))
{
task=get_idle_task(0);
if(!task){
fclose(f);
printf("get idle task fail...\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) p task
$15 = (struct task_struct *) 0x7f1340000b70

(gdb) s
428 }

。。。

。。。

### 在get_idle_task 返回后,task 地址为0x40000b70
41 if(!task){
(gdb) s
46 task->cmd=BINDATA_DEC;
(gdb) p task
$16 = (struct task_struct *) 0x40000b70
(gdb) p *task

Cannot access memory at address 0x40000b70

(gdb)

### task 地址在get_idle_task函数内为 0x7f1340000b70 ,get_idle_task返回后为0x40000b70
变短了,是编译选项的问题? 如何解决? 什么原因导致的

求解答,谢谢
...全文
308 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
___________y 2015-02-05
  • 打赏
  • 举报
回复
应该是缺少了函数 get_idle_task() 的声明. 这个问题中,64位下,调用get_idle_task()后,编译器把函数的返回值看成了默认的int类型,于是只截出了其中32bit出来(但地址是64位的). 而在32位下,地址也是32位,被当成整型时,赋值过程没有截断,所以表面上没有发生问题。
mymtom 2015-01-05
  • 打赏
  • 举报
回复
从行号上看: get_idle_task 函数定义位于 400 多行, read_ab_file 函数位于40多行 在文件的开头加上get_idle_task函数的声明应该能解决问题。

struct task_struct* get_idle_task(struct task_pool_struct* pool);
zhxianbin 2014-12-26
  • 打赏
  • 举报
回复
看起来挺诡异的,是每次必现吗?
zuxi 2014-12-26
  • 打赏
  • 举报
回复
这行task=get_idle_task(0); 之后,task->cmd=BINDATA_DEC;这行之前有没有其他代码? 如果有的话看看有没有修改task的可能。 ps:用valgrind跟踪一下应该能看出一些问题。

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧