Cannot access memory at address

newpeng 2011-08-17 09:55:20
一个收发数据的程序,线程里面调用了如下函数,函数里面只有两个事先初始化全局变量,别的变量都是线程传入的局域变量和内部自定义变量,经常会出现 SendFF (cid=Cannot access memory at address)
int slen = sizeof(struct sockaddr);
struct timeval timeo;
socklen_t iLen = sizeof(timeo);
bool MyIni(int & cid,const string & ip,const int & port)
{
if(cid>0)
{
close(cid);
cid = 0;
}
struct sockaddr_in c_addr;
bzero(&c_addr,sizeof(c_addr));
c_addr.sin_family=AF_INET;
c_addr.sin_port=htons(port);
c_addr.sin_addr.s_addr = inet_addr(ip.c_str());
if((cid=socket(AF_INET,SOCK_STREAM,0))==-1) return false;
fd_set set;
FD_ZERO(&set);
FD_SET(cid,&set);
timeval tm;
tm.tv_sec = 1;
tm.tv_usec = 50000;
if(select(cid+1, NULL, &set, NULL, &timeo)==-1){close(cid);cid=0;return false;}
signal(SIGPIPE, SIG_IGN);
if(connect(cid,(struct sockaddr *)(&c_addr),slen)==-1)
{
close(cid);
cid = 0;
return false;
}
return true;

}
bool SendFF(int & cid,const string & msg,int & l,const int & fn,const string & ip,const int & port,string & str)
{
if(cid<=0 && !MyIni(cid,ip,port)) return false;
if (setsockopt(cid,SOL_SOCKET,SO_SNDTIMEO,&timeo,iLen) == -1) return false;
if((l=send(cid,msg.c_str(),msg.length(),MSG_NOSIGNAL))<=0)
{
if(!MyIni(cid,ip,port)) return false;
if((l=send(cid,msg.c_str(),msg.length(),MSG_NOSIGNAL))<=0) return false;
}
char buf[50];
str = "";
int len=0,k=its(fn).length();
if (setsockopt(cid,SOL_SOCKET,SO_RCVTIMEO,&timeo,iLen) == -1) return false;
while((l = recv(cid,buf,50,0))>0)
{
str += string(buf,l);
len += l;
if(len >= k) break;
}
if(str.length()>k) str = str.substr(0,k);
if(atoi(str.c_str()) == fn) return true;
else return false;
}
bool SendF(int & cid,const string & msg,int & l,const int & fn,const string & ip,const int & port,string & str)
{
if(!SendFF(cid,msg,l,fn,ip,port,str))
{
if(cid>0)
{
close(cid);
cid=0;
}
return false;
}
return true;
}






-bash-3.2$ gdb ./receive_file.out ./core.25328
GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-23.el5)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols

warning: core file may not match specified executable file.
[New Thread 25344]
[New Thread 25343]
[New Thread 25341]
[New Thread 25340]
[New Thread 25339]
[New Thread 25338]
[New Thread 25337]
[New Thread 25336]
[New Thread 25335]
[New Thread 25334]
[New Thread 25333]
[New Thread 25332]
[New Thread 25328]
Reading symbols from /lib64/libpthread.so.0...(no debugging symbols found)...done.
Loaded symbols for /lib64/libpthread.so.0
Reading symbols from /usr/lib64/libstdc++.so.6...(no debugging symbols found)...done.
Loaded symbols for /usr/lib64/libstdc++.so.6
Reading symbols from /lib64/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libm.so.6
Reading symbols from /lib64/libgcc_s.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib64/libgcc_s.so.1
Reading symbols from /lib64/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Core was generated by `./receive_file.out'.
Program terminated with signal 11, Segmentation fault.
#0 0x000000000040824c in SendFF (cid=Cannot access memory at address 0xb1e98
) at ./recvf.cpp:1379
1379 if(cid<=0 && !MyIni(cid,ip,port)) return false;
(gdb) bt
Cannot access memory at address 0xb1f28
(gdb) where
Cannot access memory at address 0xb1f28
(gdb) quit
...全文
2092 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
newpeng 2011-08-24
  • 打赏
  • 举报
回复
Program terminated with signal 11, Segmentation fault.
#0 0x000000000040817e in its (n=@0x1047d60ffc) at ./recvf.cpp:320
320 sprintf(GBUFF,"%d",n);
(gdb) where
#0 0x000000000040817e in its (n=@0x1047d60ffc) at ./recvf.cpp:320
#1 0x00000000004083c5 in SendFF (cid=0x47d60ff8, msg=..., l=@0x47d60ff4, fn=@0x1047d60ffc, ip=..., port=@0x47d60ff0, str=..., timeo=..., iLen=@0x47d60f9c) at ./recvf.cpp:1384
#2 0x0000000000408655 in SendF (cid=0x47d60ff8, msg=..., l=@0x47d60ff4, fn=@0x47d60ffc, ip=..., port=@0x47d60ff0, str=..., timeo=..., iLen=@0x47d60f9c) at ./recvf.cpp:1398
#3 0x0000000000408e28 in SendTo (args=0x3) at ./recvf.cpp:1444
#4 0x000000367aa0673d in start_thread () from /lib64/libpthread.so.0
#5 0x0000003679ed3d1d in clone () from /lib64/libc.so.6
newpeng 2011-08-24
  • 打赏
  • 举报
回复
int slen = sizeof(struct sockaddr);
struct timeval timeo;
socklen_t iLen = sizeof(timeo);
bool MyIni(struct sockaddr_in & c_addr,int & cid,const string & ip,const int & port)
{
if(cid>0)
{
close(cid);
cid = 0;
}
bzero(&c_addr,sizeof(c_addr));
c_addr.sin_family=AF_INET;
c_addr.sin_port=htons(port);
c_addr.sin_addr.s_addr = inet_addr(ip.c_str());
if((cid=socket(AF_INET,SOCK_STREAM,0))==-1) return false;
fd_set set;
FD_ZERO(&set);
FD_SET(cid,&set);
timeval tm;
tm.tv_sec = 1;
tm.tv_usec = 50000;
select(cid+1, NULL, &set, NULL, &timeo);
signal(SIGPIPE, SIG_IGN);
if(connect(cid,(struct sockaddr *)(&c_addr),slen)==-1)
{
close(cid);
cid = 0;
return false;
}
return true;
}
bool SendFF(struct sockaddr_in & c_addr,int & cid,const string & msg,int & l,const int & fn,const string & ip,const int & port,string & str)
{
if(cid<=0 && !MyIni(c_addr,cid,ip,port)) return false;
if (setsockopt(cid,SOL_SOCKET,SO_SNDTIMEO,&timeo,iLen) == -1) return false;
if((l=send(cid,msg.c_str(),msg.length(),MSG_NOSIGNAL))<=0)
{
if(!MyIni(c_addr,cid,ip,port)) return false;
if((l=send(cid,msg.c_str(),msg.length(),MSG_NOSIGNAL))<=0) return false;
}
char buf[50];
str = "";
int len=0,k=its(fn).length();
if (setsockopt(cid,SOL_SOCKET,SO_RCVTIMEO,&timeo,iLen) == -1) return false;
while((l = recv(cid,buf,50,0))>0)
{
str += string(buf,l);
len += l;
if(len >= k) break;
}
if(str.length()>k) str = str.substr(0,k);
if(atoi(str.c_str()) == fn) return true;
else return false;
}
bool SendF(struct sockaddr_in & c_addr,int & cid,const string & msg,int & l,const int & fn,const string & ip,const int & port,string & str)
{
if(!SendFF(c_addr,cid,msg,l,fn,ip,port,str))
{
if(cid>0)
{
close(cid);
cid=0;
}
return false;
}
return true;
}
void * SendTo(void * args)
{
pthread_detach(pthread_self());
if(Server36) return NULL;
long k=(long)args;
int i,cid=0,j,np=0,port=atoi(vSendTo[k][2].c_str());
string ss,s,ip=vSendTo[k][1];
struct sockaddr_in c_addr;
timeo.tv_sec = 1;
while(true)
{
while(np==sPos) usleep(20000);
s="";i=0;
while(np!=sPos)
{
s += ","+its(DataSend[np][0].length())+","+DataSend[np][0]+","+its(DataSend[np][1].length())+","+DataSend[np][1];
i++;
if(++np>=IPDLEN) np = 0;
if(s.length()>512000) break;
}
s = its(i)+s;
ss = s+CheckCode;

for(j=ss.length();j<96;j++) ss += " ";
ss += "end"+s;
if(!SendF(c_addr,cid,ss,j,i,ip,port,s))
{
usleep(20000);
if(!SendF(c_addr,cid,ss,j,i,ip,port,s))
{
usleep(20000);
if(!SendF(c_addr,cid,ss,j,i,ip,port,s)) continue;
}
}
}
}
jernymy 2011-08-19
  • 打赏
  • 举报
回复
顶一下
newpeng 2011-08-19
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 xiehui3651 的回复:]
创建socket的时候会卡住??要是也应该是connect的时候吧
如果用select的话是不是应该将socket设置为noblock的方式》……
[/Quote]

创建的时候不会卡,之后connect可能会卡,我是单线程发送数据给客户端,不需要用非阻塞模式,非阻塞模式也不好控制。
newpeng 2011-08-18
  • 打赏
  • 举报
回复
看到昨晚的记录,两个地址不一样。郁闷。
xiehui3651 2011-08-18
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 newpeng 的回复:]

引用 13 楼 xiehui3651 的回复:
没看明白,为什么创建socket后要select?

我要设置超时,不能让程序因为网络原因一直卡在那里吧。

现在还没有出错,等程序出错。
[/Quote]

创建socket的时候会卡住??要是也应该是connect的时候吧
如果用select的话是不是应该将socket设置为noblock的方式》?
newpeng 2011-08-17
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 qq120848369 的回复:]
C/C++ code
局部变量传什么引用?

bool SendFF(int & cid,
[/Quote]
我传地址过去,就是为了要在函数里面建立socket,这样应该没问题的吧。
难道 if((cid=socket(AF_INET,SOCK_STREAM,0))==-1) return false; 这句改变了变量地址?
qq120848369 2011-08-17
  • 打赏
  • 举报
回复
局部变量传什么引用?

bool SendFF(int & cid,
newpeng 2011-08-17
  • 打赏
  • 举报
回复
大哥,我那个局域网变量,不可能在线程运行时释放的,线程还在运行呢。不过它在调用的函数里面需要重新赋值。
wyfwx 2011-08-17
  • 打赏
  • 举报
回复
局部变量可能在你的线程运行的时候已经被释放掉了
newpeng 2011-08-17
  • 打赏
  • 举报
回复
void * SendTo(void * args)
{
pthread_detach(pthread_self());
long k=(long)args;
int i,cid=0,j,np=0,port=atoi(vSendTo[k][2].c_str());
string ss,s,ip=vSendTo[k][1];
timeo.tv_sec = 1;
while(true)
{
while(np==sPos) usleep(20000);
s="";i=0;
while(np!=sPos)
{
s += ","+its(DataSend[np][0].length())+","+DataSend[np][0]+","+its(DataSend[np][1].length())+","+DataSend[np][1];
i++;
if(++np>=IPDLEN) np = 0;
if(s.length()>512000) break;
}
s = its(i)+s;
ss = its(s.length())+","+CheckCode;
if(!SendF(cid,ss,j,i,ip,port,s))
{
usleep(20000);
if(!SendF(cid,ss,j,i,ip,port,s))
{
usleep(20000);
if(!SendF(cid,ss,j,i,ip,port,s)) continue;
}
}
}
}


调用处代码如上,它是一个独立的线程。
luciferisnotsatan 2011-08-17
  • 打赏
  • 举报
回复
哪调用的sendF,代码写下。最初哪建的cid,怎么传到sendF里的。
看错误是没权限去访问cid所在的内存地址。
newpeng 2011-08-17
  • 打赏
  • 举报
回复
cid是在线程里面定义的,线程里面需要调用这个函数。线程使用的变量(包括传入给这个函数的变量)都是局域网变量。
luciferisnotsatan 2011-08-17
  • 打赏
  • 举报
回复
cid最初是哪来的?其他线程里的局部变量?
给另一个线程传自己的局部变量,是很危险的。
newpeng 2011-08-17
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 xiehui3651 的回复:]
没看明白,为什么创建socket后要select?
[/Quote]
我要设置超时,不能让程序因为网络原因一直卡在那里吧。

现在还没有出错,等程序出错。
xiehui3651 2011-08-17
  • 打赏
  • 举报
回复
没看明白,为什么创建socket后要select?
newpeng 2011-08-17
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 luciferisnotsatan 的回复:]
int i,cid=0后打印下cid地址,看看与崩了时的地址是否相同
[/Quote]
OK,我先查看一下。
luciferisnotsatan 2011-08-17
  • 打赏
  • 举报
回复
int i,cid=0后打印下cid地址,看看与崩了时的地址是否相同
newpeng 2011-08-17
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 wyfwx 的回复:]
引用 6 楼 newpeng 的回复:
大哥,我那个局域网变量,不可能在线程运行时释放的,线程还在运行呢。不过它在调用的函数里面需要重新赋值。

SendFF所有参数都需要保持是有效的,不只id
[/Quote]

不明白红色部分的含义,我传入一个变量地址进入函数,函数里面会涉及到更改这个变量值,这应该是可以的吧?
wyfwx 2011-08-17
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 newpeng 的回复:]
大哥,我那个局域网变量,不可能在线程运行时释放的,线程还在运行呢。不过它在调用的函数里面需要重新赋值。
[/Quote]
SendFF所有参数都需要保持是有效的,不只id

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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