CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Java >  J2SE / 基础类

版主帮我看一下,是否是java的漏洞?

楼主robin_wan(爱你没商量)2006-08-18 14:32:19 在 Java / J2SE / 基础类 提问

class   staMeter{  
          public   int         iGross;  
          public   double   ratedLoad;                            
          public   double   DeviationValue_plus;        
          public   double   DeviationValue_negative;  
          public   double   MeterPrecision;                  
          public   int         iMeterStatusvalue;            
          public   int         iMeterStatusStability;    
  }  
  class   testdll  
  {  
  static  
  {  
  System.loadLibrary("javachimeitx");//载入静态库,test函数在其中实现  
  }  
  private   native   int     OpenComPort(int   iCom,int   iBaudRate);   //声明本地调用  
  private   native   int     CloseComPort(int   hd);                 private   native   staMeter   ReadDataRM(int   hd);  
                    public   int   java_OpenComPort(int   iCom,int   iBaudRate)  
  {  
  return   OpenComPort(iCom,iBaudRate);  
  }  
  public   int   java_CloseComPort(int   hd)  
  {  
  return   CloseComPort(hd);  
  }  
  public   staMeter   java_ReadDataRM(int   hd)  
  {  
  return   ReadDataRM(hd);  
  }  
  public   static   void   main(String   args[])  
  {  
   
  testdll   td   =   new   testdll();  
  int   hd=td.java_OpenComPort(1,19200);  
                        staMeter   pstateMeter=new   staMeter();  
  for(int   i=0;i<30000*10000;i++)  
  {  
  try  
  {  
                  pstateMeter=td.java_ReadDataRM(hd);  
  System.out.println(i);  
                                                              //加   System.out.println(i);一段时间后就会出错,  
                                                              //不加就没有问题。不会是DLL的问题吧。但不加就没有问题啊  
  }  
  catch   (Exception   exception)    
  {  
  exception.printStackTrace();  
  }  
  }  
       
  System.out.println("pstateMeter=td.java_ReadDataRM(hd)     3000*10000s   OK   ");  
  td.java_CloseComPort(hd);  
  }  
  }  
  问题点数:100、回复次数:26Top

1 楼healer_kx(甘草(楼主揭贴吧,我们这些上班灌水的也不容易))回复于 2006-08-18 14:40:04 得分 5

很可能出现问题啊,。  
  Top

2 楼OnlyFor_love(『勾勾手指头 一辈子不分手』)回复于 2006-08-18 14:41:25 得分 5

对调用dll不太熟悉   关注一下Top

3 楼treeroot(旗鲁特)回复于 2006-08-18 14:48:30 得分 5

和dll没关系呀  
  System.out.println(i);这句代码和其他的代码没有关系呀Top

4 楼robin_wan(爱你没商量)回复于 2006-08-18 14:53:12 得分 0

to   healer_kx(甘草(朝圣中...   ...))   :  
          哪里有可能有问题啊?  
  (1)是指system.out.println(i);有问题还是DLL中的td.java_ReadDataRM(hd)有问题。  
  (2)若DLL中的td.java_ReadDataRM(hd)有问题不什么当没有system.out.println(i)这一行的时候程序就不会出错,且能正确执行??????  
   
   
  to   treeroot(旗鲁特)   :  
        但是就是加了这一句后就出问题,我也不知是啥原因?  
  Top

5 楼jihanzhong(逍遥)回复于 2006-08-18 15:08:09 得分 0

先把错误信息贴出来看看Top

6 楼robin_wan(爱你没商量)回复于 2006-08-18 16:58:48 得分 0

当加了system.out.println(i)后一段时间,一般在i=5xx,或i=19xx时就报异常。不加则没不会出现。  
  #   An   unexpected   error   has   been   detected   by   HotSpot   Virtual   Machine:  
  #  
  #     EXCEPTION_ACCESS_VIOLATION   (0xc0000005)   at   pc=0x00aeda1c,   pid=1736,   tid=2956  
  #  
  #   Java   VM:   Java   HotSpot(TM)   Client   VM   (1.5.0_07-b03   mixed   mode,   sharing)  
  #   Problematic   frame:  
  #   j     testdll.main([Ljava/lang/String;)V+342  
  #  
  #   An   error   report   file   with   more   information   is   saved   as   hs_err_pid1736.log  
  #  
  #   If   you   would   like   to   submit   a   bug   report,   please   visit:  
  #       http://java.sun.com/webapps/bugreport/crash.jsp  
  Top

7 楼robin_wan(爱你没商量)回复于 2006-08-18 17:05:16 得分 0

DLL为C++所写,调用了5百多次后出现异常。  
  (1)应该不会是DLL的问题吧。否则一次出会出错啊。  
  (2)假设是DLL的问题,哪为什么在java中调用后,只要不加system.out.prinln(i)就不会有问题啊?  
  (3)在pstateMeter=td.java_ReadDataRM(hd);执行后使用其返回的对象也不会有问题,  
  是否更加说明了DLL没有问题???如下不会出错:  
   
                pstateMeter=td.java_ReadDataRM(hd);  
                int   int1=pstateMeter.iGross;  
                int   int2=pstateMeter。iMeterStatusvalue;  
                 
  Top

8 楼terry_yip(我只回答引起我思考的问题)回复于 2006-08-18 17:21:51 得分 5

楼主说出问题,请问报错语句是什么?  
   
  (1)应该不会是DLL的问题吧。否则一次出会出错啊。  
    这应该是dll中的内存地址操作有关系吧,你查一下DLL里面有指针的操作,又或者看看是不是什么资源没释放,再退一步,你用C++来调用这个dll一千次看看有没有错,就知道是不是JAVA的问题了。  
   
  (2)假设是DLL的问题,哪为什么在java中调用后,只要不加system.out.prinln(i)就不会有问题啊?  
   
    这个说法没什么逻辑,你再确认看看是不是真的是这样。Top

9 楼maquan('ma:kju)回复于 2006-08-18 17:30:42 得分 5

奇怪,有趣,我也想知道答案。mark   一下~~Top

10 楼robin_wan(爱你没商量)回复于 2006-08-19 11:05:32 得分 0

to   terry_yip:  
   
  (1)C++应该没有办法再调用这个DLL了。  
  (2)"这个说法没什么逻辑,你再确认看看是不是真的是这样"  
      真的是这样,不加printlnr执行3000*10000次都不会出错。  
  Top

11 楼robin_wan(爱你没商量)回复于 2006-08-19 14:49:04 得分 0

有人知道吗?版主帮帮忙吧!Top

12 楼robin_wan(爱你没商量)回复于 2006-08-20 12:19:50 得分 0

版主帮帮忙吧!  
   
  我是用C++的。主要是客户(用java的)要用到C++的DLL,  
  所以我就写了一个通讯方面的DLL,用的是JNI方式。  
  java我不熟,因此请各位多多发言了!!!!!Top

13 楼crazycy(崔毅,blog:http://www.blogjava.net/crazycy/)回复于 2006-08-20 12:58:49 得分 5

for(int   i=0;i<30000*10000;i++)  
  {  
  try  
  {  
  pstateMeter=td.java_ReadDataRM(hd);  
  System.out.println(i);  
  //加   System.out.println(i);一段时间后就会出错,  
   
  ===================================  
  初步怀疑这个i是否超过了int定义的范围呢?!  
   
  同时,jni调用处没有错误;Top

14 楼crazycy(崔毅,blog:http://www.blogjava.net/crazycy/)回复于 2006-08-20 12:59:45 得分 5

楼主,你这样来,你看看i打印出的最大值是多少?  
   
  具体的错误信息?  
   
  都贴出来看看Top

15 楼robin_wan(爱你没商量)回复于 2006-08-21 09:14:15 得分 0

不是这样的,当i(max)=3000时也会出错。出错时i一般等于5百多,或19XX,一直都在此区间  
  内有错。  
  如下也会有错:  
  for(int   i=0;i<3000;i++)  
  {  
  try  
  {  
        pstateMeter=td.java_ReadDataRM(hd);  
        System.out.println(i);  
        //加   System.out.println(i);一段时间后就会出错,  
  }  
  }  
   
   
  Top

16 楼robin_wan(爱你没商量)回复于 2006-08-21 09:23:59 得分 0

怀疑是C++中资源没有释放造成,现贴上C++   DLL的代码:  
  (1)原本在其中加上了try{}catch(){},但是也不能捕捉到异常。  
  (2)怀疑jfieldID等部分资料没有释放,但是如果没有释放的话java中不加system.out.print(i)也应该有错啊。  
  (3)怀疑jfieldID等部分资料没有释放,但是怎样释放呢?加   if(ival_Gross   )delete   ival_Gross   ;反而C++中有异常。不加c++正常。  
  JNIEXPORT   jobject   JNICALL   Java_testdll_ReadDataRM  
      (JNIEnv   *jenv,   jobject   jobj,   jint   hd){  
                  char   *ptr;  
                  int     j;  
                  int     RetryNum;  
                  char   back[280+20];  
                  char   cmdstr[10];  
                  staMeter   pstaMeter;  
   
                  //INIT  
                  pstaMeter.iGross=10;  
                  pstaMeter.iMeterStatusvalue=0;  
                  pstaMeter.iMeterStatusStability=0;  
                  pstaMeter.ratedLoad=80000.0;  
                  pstaMeter.DeviationValue_plus=0;  
                  pstaMeter.DeviationValue_negative=0;  
                  pstaMeter.MeterPrecision=0;  
   
                  //获取Java中的实例类  
                  jclass   objectClass   =   (jenv)->FindClass("staMeter");  
                  if(objectClass)  
                  {  
                          jfieldID   ival_Gross                                                     =   (jenv)->GetFieldID(objectClass,"iGross","I");  
                          jfieldID   ival_MeterStatusvalue                               =   (jenv)->GetFieldID(objectClass,"iMeterStatusvalue","I");  
                          jfieldID   ival_MeterStatusStability                       =   (jenv)->GetFieldID(objectClass,"iMeterStatusStability","I");  
                          jfieldID   dval_ratedLoad                                             =   (jenv)->GetFieldID(objectClass,"ratedLoad","D");  
                          jfieldID   dval_DeviationValue_plus                         =   (jenv)->GetFieldID(objectClass,"DeviationValue_plus","D");  
                          jfieldID   dval_DeviationValue_negative                 =   (jenv)->GetFieldID(objectClass,"DeviationValue_negative","D");  
                          jfieldID   dval_MeterPrecision                                   =   (jenv)->GetFieldID(objectClass,"MeterPrecision","D");  
   
                          (jenv)->SetIntField(jobj,ival_Gross,pstaMeter.iGross);  
                          (jenv)->SetIntField(jobj,ival_MeterStatusvalue,pstaMeter.iMeterStatusvalue);  
                          (jenv)->SetIntField(jobj,ival_MeterStatusStability,pstaMeter.iMeterStatusStability);  
                          (jenv)->SetDoubleField(jobj,dval_ratedLoad,pstaMeter.ratedLoad);  
                          (jenv)->SetDoubleField(jobj,dval_DeviationValue_plus,pstaMeter.DeviationValue_plus);  
                          (jenv)->SetDoubleField(jobj,dval_DeviationValue_negative,pstaMeter.DeviationValue_negative);  
                          (jenv)->SetDoubleField(jobj,dval_MeterPrecision,pstaMeter.MeterPrecision);  
                          return   jobj;  
                  }  
                  else  
                  {  
                        return   NULL;  
                  }  
  }  
   
  Top

17 楼zhmt(孜风)回复于 2006-08-21 09:27:29 得分 5

路过,友情up!Top

18 楼wmzsl(王明哲)回复于 2006-08-21 09:32:03 得分 0

都什么和什么啊呵呵Top

19 楼bigc2000(公元2005年4月9日)回复于 2006-08-21 10:24:52 得分 30

这种异常,肯定是C++部分,想都不用想,  
  hs_err_pid1736.log  
  请把这个文件贴出来看看。  
   
  还有,下次看到EXCEPTION_ACCESS_VIOLATION(0xc0000005)  
  这个时候,就可以断定是Native   api非法的内存访问。   (java的虚拟机已经十分完美了,不用你怀疑)  
  我是菜鸟,只知道这几种最有可能非法访问导致上面错误(堆栈益处,映射文件数据溢出,野指针修改的数据破坏了java上层的数据)。  
   
  你上面的情况,可能就是第一种资源不释放或者多次释放同一个指针。  
   
  看你的代码,(由于不全)好像你每次返回的都是同一个对象return   jobj;也就是掉用者。  
  pstateMeter,td下面怎么使用的?  
   
  还有就是,你这个就是简单的clone,干吗要整个如此麻烦的jni   函数?  
  Top

20 楼maquan('ma:kju)回复于 2006-08-21 11:00:24 得分 10

看看你的   C++   程序的   calling   convention   是不是跟   JNI   要求的一致。  
   
  虽然我觉得这个环节出错的可能性不大(毕竟   .h   是   javah   生成的嘛),不过还是确认一下为好。我总觉得从现象上看好像跟这个有点关系。Top

21 楼robin_wan(爱你没商量)回复于 2006-08-21 15:38:05 得分 0

to   bigc2000(公元2005年4月9日):  
   
  (1)代码已经很全了。Java_testdll_ReadDataRM()主要是读外设然后反回相关的信息。  
  (2)“还有就是,你这个就是简单的clone,干吗要整个如此麻烦的jni   函数?”  
          当然不会如此简单了。  
   
          do_something();   真正使用的时侯,这里要加上读仪表的处理。现在没有加也会有错。  
            //获取Java中的实例类  
            jclass   objectClass   =   (jenv)->FindClass("staMeter");  
  (3)java中为何不加system.out.print(i);就不会有错。C++部分还是同样调用过了,????Top

22 楼robin_wan(爱你没商量)回复于 2006-08-21 16:40:24 得分 0

初步找到问题,主要是如下语句有问题:  
  (jenv)->SetIntField(jobj,ival_Gross,pstaMeter.iGross);  
  (jenv)->SetIntField(jobj,ival_MeterStatusvalue,pstaMeter.iMeterStatusvalue);  
  (jenv)->SetIntField(jobj,ival_MeterStatusStability,pstaMeter.iMeterStatusStability);  
  (jenv)->SetDoubleField(jobj,dval_ratedLoad,pstaMeter.ratedLoad);  
  (jenv)->SetDoubleField(jobj,dval_DeviationValue_plus,pstaMeter.DeviationValue_plus);  
  (jenv)->SetDoubleField(jobj,dval_DeviationValue_negative,pstaMeter.DeviationValue_negative);  
  (jenv)->SetDoubleField(jobj,dval_MeterPrecision,pstaMeter.MeterPrecision);  
   
  将其改为一条语句都出错如原样,也将pstaMeter.iMeterStatusvalue直接用10代替  
  也都一样。齐怪了?????  
          jenv->SetIntField(jobj,ival_Gross,10);  
  Top

23 楼maquan('ma:kju)回复于 2006-08-21 17:34:30 得分 5

>   An   error   report   file   with   more   information   is   saved   as   hs_err_pid1736.log  
   
  楼主检查过   hs_err_pid1736.log   这个文件吗?有什么发现吗?  
   
  能不能帖出来让大家看看~~Top

24 楼bigc2000(公元2005年4月9日)回复于 2006-08-21 22:48:51 得分 0

To   :     robin_wan   (爱你没商量)      
   
  我已经说了,你怎么每次都返回同一个jobj,也就是说,如果在java端没有  
   
  pstateMeter=td.java_ReadDataRM(hd);  
  这句调用者是td,可是C++返回的也是td对象本身,所以相当于   pstateMeter   =   td;  
   
    jclass   objectClass   =   (jenv)->FindClass("staMeter");  
  这个是查找class,而不是对象实例,也就是查找已经被加载且已定义的一个class而已;  
  jobj是实例,而不是表示类。Top

25 楼robin_wan(爱你没商量)回复于 2006-08-22 09:28:31 得分 0

To   bigc2000(公元2005年4月9日):  
        非常感激你及上楼上各位的发言!  
        还有如下疑问:  
   
      (一)“pstateMeter=td.java_ReadDataRM(hd);这句调用者是td,可是C++返回的也是td对象本身,所以相当于   pstateMeter   =   td;”  
   
        <Ⅰ>不对呀,java中原型是public   staMeter   java_ReadDataRM(int   hd)返回的是类staMeter的引用。C++中实际上是给这个类的各个属性赋值。  
   
        <Ⅱ>因为C++生成的DLL无法知道调用者(java程序)生成的是  
  pstateMeter     (语句staMeter   pstateMeter=new   staMeter();)  
   
      因此C++中只能用:  
      JNIEXPORT   jobject   JNICALL   Java_testdll_ReadDataRM    
            (JNIEnv   *jenv,   jobject   jobj,   jint   hd)  
      {  
                注:java中Java_testdll_ReadDataRM()应该返回staMeter    
                        用javah   testdll   后生成的原型只能返回的是jobject。    
   
                //用下句获取Java中的实例类。  
                  jclass   objectClass   =   (jenv)->FindClass("staMeter");  
                //用下句获取Java中的实例类的一个名iGross的Field。  
                  jfieldID   ival_Gross=   (jenv)->GetFieldID(objectClass,"iGross","I");  
                //用下句给实例类的一个名iGross的Field赋值。  
                  (jenv)->SetIntField(jobj,ival_Gross,pstaMeter.iGross);  
                //用下句返回实例类的指针  
                return   jobj;  
      }  
   
  (二)如果我的理解有误,哪象我这样的需求(返回一个类的引用,C++中实际就是返回一个结构体类型),到底要怎样写才能实现呢。  
   
   
  Top

26 楼bigc2000(公元2005年4月9日)回复于 2006-08-23 20:46:44 得分 15

java_ReadDataRM  
  将该函数修改下增加一个参数  
  public   void   java_ReadDataRM(staMeter   pstateMeter,int   hd)  
  {  
  return   ReadDataRM(pstateMeter,hd);  
  }  
   
  相应C++部分就不用return了。  
  C++部分JNIEXPORT   jobject   JNICALL   Java_testdll_ReadDataRM  
      (JNIEnv   *env,   jobject   jobj,   jobject   pStaMeter,   jint   hd)  
  第一个jobj相当于this,第二个个开始才是参数。  
   
  要不按你说的就这样,在c++部分分配,  
   
  实在看不懂你说的。     这句话---   注:java中Java_testdll_ReadDataRM()应该返回staMeter    
                        用javah   testdll   后生成的原型只能返回的是jobject。    
  FindClas是查找类(也就是类的说明,而不是实例)第一个jobj才是是类,它就是td。  
  好了不说了。Top

相关问题

关键词

得分解答快速导航

  • 帖主:robin_wan
  • healer_kx
  • OnlyFor_love
  • treeroot
  • terry_yip
  • maquan
  • crazycy
  • crazycy
  • zhmt
  • bigc2000
  • maquan
  • maquan
  • bigc2000

相关链接

  • CSDN Java频道
  • Java类图书
  • Java类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo