程序调试没有问题,运行就出错。

tomyangguang 2015-03-04 10:40:47
最近在需做pcap文件解析,开始大部分代码都是C写的,后来要求有界面,就选择了MFC界面。经过反复的debug后,感觉是这段代码的问题,不知道问题出现在哪里?
void SessionTree::GetHTML1(char * path)
{
pHttpFile p = httpfile;
int pathlen = strlen(path);
char * title = (char *)malloc(pathlen + 1);
memcpy(title,path,pathlen);
memcpy(title + pathlen,"\\",1);
memcpy(title + pathlen + 1,"\0",1);
string report = title;
report +="report2.txt";
ofstream out;
out.open(report.c_str(),ios::out|ios::trunc|ios::binary);
if (!out)
{
cout<<"open error";
}
while(p != NULL)
{
FILE * file;
pcap_file_header file_header;
pcap_pkthdr pcap_header;
ip_header ih;
tcp_header th;

vector<char *> vec;
FILE * temptxtfile = NULL;

fopen_s(&file,p->filename,"rb");
if (file == NULL)
{
exit(0);
}
//计算整个文件的字节数
fseek(file,0,SEEK_END);
u_long Lenght = ftell(file);
fseek(file,0,SEEK_SET);
//读取文件头
fread_s((void *)&file_header,sizeof(pcap_file_header),sizeof(pcap_file_header),1,file);
u_long Index = 24;
while(Index < Lenght)
{
//读取包头
fread_s((void *)&pcap_header,sizeof(pcap_header),sizeof(pcap_header),1,file);
fseek(file,14 ,SEEK_CUR);
fread_s((void *)&ih,sizeof(ip_header),sizeof(ip_header),1,file);
if (((ih.ver_ihl & 0x0f) * 4-20) >0)
{
fseek(file,((ih.ver_ihl & 0x0f) * 4-20),SEEK_CUR);
}
fread_s((void *)&th,sizeof(tcp_header),sizeof(tcp_header),1,file);
int DataLength = ntohs(ih.tlen)- (ih.ver_ihl & 0x0f) * 4 -(th.dataoffset>>4)*4;
//////////////////////////////////////////////////////////////////////////
//获取标题,subfile信息,
//问题出现了一对会话之间没有换行符。
//////////////////////////////////////////////////////////////////////////
if (DataLength > 0)
{
fseek(file,(th.dataoffset>>4)*4 - 20,SEEK_CUR);
//读取数据
char * data = (char *)malloc(DataLength);

memset(data,0,DataLength);


fread_s(data,DataLength,DataLength,1,file);
data[DataLength] = '\0';
fseek(file,-((th.dataoffset>>4)*4 - 20 + DataLength),SEEK_CUR);
//只有是GET请求或者HTTP/1.1 200 OK才进入
if (temptxtfile == NULL && (strncmp("GET ",data,strlen("GET ")) == 0 ||
strncmp("HTTP/1.1 200 OK",data,strlen("HTTP/1.1 200 OK")) == 0 || strncmp("POST /",data,strlen("POST /")) == 0))
{
char seps[] = "\r\n";
char *next_token = NULL;
char * txt = (char *)malloc(strlen(data)+1);
memcpy(txt,data,strlen(data) + 1);
//strncpy_s(txt,strlen(txt),data,strlen(data));
char * token = strtok_s(txt,seps,&next_token);
while (token != NULL)
{
if (strncmp("GET / HTTP/1.1",token,strlen("GET / HTTP/1.1")) == 0)
{
pushData(data);

break;
}
else if (strncmp("GET /",token,strlen("GET /")) == 0)//|| strncmp("POST /",data,strlen("POST /")) == 0 排除POST请求,后面好做一些
{
if (temptxtfile == NULL)
{
char * filename = (char *)malloc(strlen(token) + pathlen + 1);
memcpy(filename,title,pathlen + 1);
char *filename1 = StrReplace(token);
memcpy(filename + pathlen + 1,"\0",1);
strcat_s(filename,strlen(token) + pathlen + 2,filename1);
//创建文件存储会话数据
p->txtfilename = filename;
fopen_s(&temptxtfile,filename,"wb+");
}
fwrite(data,DataLength,1,temptxtfile);
break;
}
else if (strncmp("Content-Location: http://",token,strlen("Content-Location: http://")) == 0)
{
int i = strlen(token);
int j = strlen("Content-Location: http://");
char * filename = (char *)malloc(i - j+ pathlen + 10);
memcpy(filename,title,pathlen + 1);
char *filename1 = StrReplace(token + j);
memcpy(filename + pathlen + 1,"\0",1);
strcat_s(filename,i - j + pathlen + 10,filename1);
//创建文件存储会话数据
if (temptxtfile == NULL)
{
p->txtfilename = filename;
fopen_s(&temptxtfile,filename,"wb");
}
//写入存储的数据
char * str = popData();
fwrite(str,strlen(str),1,temptxtfile);
fwrite(data,DataLength,1,temptxtfile);
break;
}
token = strtok_s(NULL,seps,&next_token);
}
}
else
{
if (temptxtfile == NULL)
{
pushData(data);
//vec.push_back(data);
}
else
{
if (strncmp("GET ",data,strlen("GET ")) == 0)
{
fwrite("\r\n\r\n\r\n\r\n\r\n",strlen("\r\n\r\n\r\n\r\n\r\n"),1,temptxtfile);
}
fwrite(data,DataLength,1,temptxtfile);
}
}
}
fseek(file,pcap_header.caplen -14 - 20 - 20,SEEK_CUR);
Index += pcap_header.caplen + 16;
}
if (temptxtfile != NULL)
{
out<<p->filename<<"--> +"<<p->txtfilename<<"\r\n";
}
if (temptxtfile != NULL)
{
fclose(temptxtfile);
}
//记录对应的对应的关系
p = p->next;
}
out.close();
}


出现问题是这样的
...全文
892 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
一朵格桑花 2015-03-05
  • 打赏
  • 举报
回复
单步调试 看看在哪句崩溃的
xiaohuh421 2015-03-04
  • 打赏
  • 举报
回复
还有, 你的内存申请, 只有申请, 没有释放, 也没有判断是否申请失败. 当你的函数调用多次后, 完全可能因为内存不足, 导致分配失败, 然后你又未判断这种情况, 程序也会崩溃掉.
xiaohuh421 2015-03-04
  • 打赏
  • 举报
回复
char * title = (char *)malloc(pathlen + 1); memcpy(title,path,pathlen); // pathlen memcpy(title + pathlen,"\\",1); //pathlen+1 memcpy(title + pathlen + 1,"\0",1); //pathlen+2 这里已经越界. 你访问的空间大小为 pathlen+2, 所以你空间申请少了. 可能会导致后面的变量被修改. data[DataLength] = '\0'; 这里也是越界了. 其它地方就没有细看了. 做程序的, 调试必不可少. 你可以使用F5运行程序, 在程序崩溃的时候, 一般会弹出调试选 项, 选择调试, 然后程序一般就会中断在出错的地方了,
赵4老师 2015-03-04
  • 打赏
  • 举报
回复
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止。
天律界中子 2015-03-04
  • 打赏
  • 举报
回复
如果你用的是VS2008的话,你可以看输出当中,是否提示有XXXX可能的异常。如果有的话,点击“调试”菜单,选择异常,勾上你觉得可能的异常,然后再执行那段程序,可能会有所帮助。 另一种办法,先运行程序Release,然后使用VS2008附加到进程,然后执行导致崩溃的操作,运气好的话,也能看出些东西来。
wyc761024 2015-03-04
  • 打赏
  • 举报
回复
就是构造个文件路径,不需要这么麻烦,多次调用memcpy,直接一次sprintf就够用了。这种变量没有必要malloc出来,定义个临时的字符数组即可。这种溢出不太容易查出来,随机崩溃会让你人也崩溃。

24,854

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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