免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6387 | 回复: 13
打印 上一主题 下一主题

[C] Free的时候Core,大伙帮我分析下,所有我能想到的方法都试过了,源码和Core内容都有 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-11-06 18:08 |只看该作者 |倒序浏览
这个是一个数据同步程序里面的(ProC代码),需要从一个接口表里取出一个CLOB的数据,因为这里面的数据长度不定,所以用的是动态申请的char指针来存放取出的数据,数据是Utf8的XML报文,取出来解析之后需要释放掉,在下次循环又根据CLOB的长度重新申请一片内存。
     现在的问题是,跑几条数据之后Free就会Core,在取出来之后到解析到释放都没有改变其内容。程序大概流程如下:

select * from interface; /*从接口表取出数据,一次最多500条记录,取出来是放在一个数据里*/

for(i=0;i<500;i++)
   如果interface表指示出一条记录还需要到明细表里取的时候,就如我前面陈述的,需要动态申请一个空间,因为明细表的数据是一个CLOB类型的数据;
  取出来之后解析报文;
  解析之后就需要释放这个空间;
  (就是在这里,跑几条数据就会Core)
......


   还请各位指点一下。主机是HP-UX,ORACLE10G,malloc,free哭函数。
  
   申请的空间的地址在赋值前我打印了,解析后也打印了,释放前打印了都是一样的。程序不是一跑就Core,一般都是跑了个7-8条记录就core。

  程序代码在6楼。gdb还不会用,就会这个where。

  这个Core文件里的:

HP gdb 5.7 for HP Itanium (32 or 64 bit) and target HP-UX 11.2x.
Copyright 1986 - 2001 Free Software Foundation, Inc.
Hewlett-Packard Wildebeest 5.7 (based on GDB) is covered by the
GNU General Public License. Type "show copying" to see the conditions to
change it and/or distribute copies. Type "show warranty" for warranty/support.
..
Core was generated by `orderDealBoss'.
Program terminated with signal 11, Segmentation fault.
SEGV_MAPERR - Address not mapped to object

warning: Load module /oracle/app/oracle/product/10.0/lib/libclntsh.so.10.1 has been stripped.  
Debugging information is not available.


warning: Load module /oracle/app/oracle/product/10.0/lib/libnnz10.so has been stripped.  
Debugging information is not available.

#0  0xc00000000035db40:0 in tree_delete+0x20 () from /usr/lib/hpux64/libc.so.1
(gdb) where
#0  0xc00000000035db40:0 in tree_delete+0x20 () from /usr/lib/hpux64/libc.so.1
#1  0xc000000000358fa0:0 in real_free+0x600 () from /usr/lib/hpux64/libc.so.1
#2  0xc000000000363cf0:0 in free+0x170 () from /usr/lib/hpux64/libc.so.1
#3  0x4000000000013bd0:0 in PubLogicDeal () at orderDealBoss.cp:536
#4  0x400000000001bd70:0 in PubDealTaskOneDB () at pubOrderXml.cp:771
#5  0x400000000001b3e0:0 in PubInitTaskListOneDB () at pubOrderXml.cp:671
#6  0x40000000000155c0:0 in main () at orderDealBoss.cp:675
(gdb)

[[i] 本帖最后由 Hex_water 于 2009-11-8 00:22 编辑 [/i]]

论坛徽章:
0
2 [报告]
发表于 2009-11-07 11:23 |只看该作者
如果真的是这个流程的话,应该是没有问题的。

另外,我觉得这种程序流程不好,还是在循环之前,申请一个“足够”大的内存,循环完了再释放吧。

论坛徽章:
0
3 [报告]
发表于 2009-11-07 11:24 |只看该作者
在解析的过程中,是不是越界了?

论坛徽章:
0
4 [报告]
发表于 2009-11-07 14:57 |只看该作者
原帖由 naihe2010 于 2009-11-7 11:23 发表
如果真的是这个流程的话,应该是没有问题的。

另外,我觉得这种程序流程不好,还是在循环之前,申请一个“足够”大的内存,循环完了再释放吧。




       如果在循环里我用数组的都就不会Core,但是数组就得事先定义一个大小,而CLOB字段的数据,最大可以达到4G字节,所以才改为根据CLOB字段实际长度动态申请内存空间。
       循环500次,是因我前面一次取了500条记录,每条记录有可能有明细数据,有可能没有,所以是动态申请的,如果没有明细数据就只需要4000字节就够了。

论坛徽章:
0
5 [报告]
发表于 2009-11-07 15:04 |只看该作者
原帖由 naihe2010 于 2009-11-7 11:24 发表
在解析的过程中,是不是越界了?


   调用解析函数的时候是用另外一个char指针传进去的,而且我申请的空间比实际数据长128字节,实际数据是XML报文,解析到结束标签就不会再往后解析了,应该没有越界的。解析函数一切都正常,解析函数也不改变任何的数据。如果是解析的过程越界了,会不会直接在解析的时候就已经Core了。

论坛徽章:
0
6 [报告]
发表于 2009-11-07 15:09 |只看该作者
char *XmlTemp=NULL;
char *XmlData=NULL;
int XmlLength=4001;
init(v_det_flag);
strncpy(v_det_flag,v_order_data[i].det_flag,1);
if (strcmp(v_det_flag,ORDERDETFLAG_Y)==0)        /*如果有明细数据*/
{
        EXEC SQL SELECT LENGTH(INTERFACE_DATA) INTO :XmlLength FROM wOrderReceiptDet WHERE ORDER_ACCEPT=:v_order_data[i].order_accept;

        XmlTemp=NULL;
        XmlTemp=(char *)malloc((XmlLength+128)*sizeof(char));
        memset(XmlTemp,'3',sizeof(char)*XmlLength+128);
        if(XmlTemp==NULL)
        {
                PRINTLOG("D[%s][%s][%d]分配内存失败\n",__FILE__,__FUNC__,__LINE__);
                continue;
        }

        EXEC SQL SELECT NVL(TRIM(INTERFACE_DATA),' ') INTO :XmlTemp FROM WORDERRECEIPTDET WHERE ORDER_ACCEPT=:v_order_data[i].order_accept;
        sqlcode=SQLCODE;
        if (sqlcode!=SQLOK)
        {
                EXEC SQL ROLLBACK;
                free(XmlTemp);
                XmlTemp=NULL;

                printlog("D[%s][%s][%d]Select wOrderReceiptDet Error,SQLCODE=[%d],SQLERRMSG=[%s]\n",__FILE__,__FUNC__,__LINE__,sqlcode,SQLERRMSG);

                continue;
        }

        strim(XmlTemp);
        XmlData=XmlTemp;
}
else
{
        XmlData=&v_order_data[i].interface_data;
}

/*解析工单*/
MsgBodyType        vMsgBodyType;
memset(&vMsgBodyType,0,sizeof(MsgBodyType));

int RecordNum=0;
v_ret=OrderParseXml(&vMsgBodyType,XmlData,v_order_data[i].order_type,XmlLength,&RecordNum);
XmlData=NULL;
if (v_ret!=0)
{
        OrderDestroyMsgBody(&vMsgBodyType);
        if(XmlTemp!=NULL)
        {
                free(XmlTemp);
                XmlTemp=NULL;
        }
        printlog("D[%s][%s][%d]Process [%s] order_accept=[%ld] OrderParseXml error[%d]\n",
                __FILE__,__FUNC__,__LINE__,i_table_label, v_order_data[i].order_accept, v_ret);

        continue;
}

if(XmlTemp !=NULL)
{
        free(XmlTemp);     /*就是在这个释放会Core,不是程序一跑就Core,一般都是跑7-8条数据就Core*/
        XmlTemp=NULL;
}


这是这块的代码,大家还有没有别的思路。

[[i] 本帖最后由 Hex_water 于 2009-11-7 20:38 编辑 [/i]]

论坛徽章:
0
7 [报告]
发表于 2009-11-07 17:19 |只看该作者
。。。。。

论坛徽章:
0
8 [报告]
发表于 2009-11-07 17:48 |只看该作者
原帖由 Hex_water 于 2009-11-7 14:57 发表




       如果在循环里我用数组的都就不会Core,但是数组就得事先定义一个大小,而CLOB字段的数据,最大可以达到4G字节,所以才改为根据CLOB字段实际长度动态申请内存空间。
       循环500次,是因我前 ...


我知道动态申请,我说的也是动态申请。你在500次的循环里,可能申请的最大值,在循环前就申请它,在循环里不要重要申请,对性能有好处。
但你如果一条数据有4G的话,那就不好说了。

论坛徽章:
0
9 [报告]
发表于 2009-11-07 18:08 |只看该作者
原帖由 Hex_water 于 2009-11-7 15:09 发表
char *XmlTemp=NULL;
char *XmlData=NULL;
int XmlLength=4001;
init(v_det_flag);
strncpy(v_det_flag,v_order_data.det_flag,1);
if (strcmp(v_det_flag,ORDERDETFLAG_Y)==0)        /*如果有明细数据*/
{
        E ...



你这块代码虽然错误不少,但是最可疑的地方在
v_ret=OrderParseXml(&vMsgBodyType,XmlData,v_order_data.order_type,XmlLength,&RecordNum);
这句里的XmlLength,如果
{
        XmlData=&v_order_data.interface_data;
}
的话,就没有计算,是默认值4001。对么?

论坛徽章:
0
10 [报告]
发表于 2009-11-07 18:58 |只看该作者
原帖由 naihe2010 于 2009-11-7 18:08 发表



你这块代码虽然错误不少,但是最可疑的地方在
v_ret=OrderParseXml(&vMsgBodyType,XmlData,v_order_data.order_type,XmlLength,&RecordNum);
这句里的XmlLength,如果
{
        XmlData=&v_order_da ...


对,因为不取明细数据的话,最多就4000字节的长度。有错误的地方还请指出来。

[ 本帖最后由 Hex_water 于 2009-11-7 19:01 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP