J2ME 混淆的应用程序堆栈跟踪

Posted

技术标签:

【中文标题】J2ME 混淆的应用程序堆栈跟踪【英文标题】:J2ME obfuscated app stacktrace 【发布时间】:2013-07-29 15:33:42 【问题描述】:

我在 nokia N95(不是我写的)上调试 J2ME(用 eclipse 编写)代码试图找出错误并打印出堆栈跟踪给了我这个:

  03:08:479 TSKR. Error:
  java.lang.NullPointerException:   0
 - java.lang.String.<init>(), bci=6
  - v.b(), bci=9
 - v.e(), bci=805
 - v.e(), bci=3

谁能帮我理解一下?哪条线,在哪里寻找以及有没有办法理解它或至少获得一些有价值和有用的信息。 谢谢

更新

对不起..这是引发错误的函数:

public void     bluetoothFileProcessBytes()//--------tracing out of memory error
    try

    partCurrentLoop++;          
    fileCurrentLoop++;

    debug("Loop " + fileCurrentLoop + " of " + fileTotalLoops);

    bluetoothUpdateBytes(fileDataString.length());  
    guiUpdateProgressBar(true, partCurrentLoop, partTotalLoops);

    // LOOP Step 2: If there is no byte[] created for storing the bytes, create it. 

    if (fileBytesIsEmpty) 

        if (partCurrentNumber == partTotalNumber)
        
            fileBytes = new byte[fileSize % (loopsPerHttpComm * BYTES_PER_LOOP)];
        
        else    fileBytes = new byte[loopsPerHttpComm * BYTES_PER_LOOP];                    


       
    fileBytesIsEmpty = false;


    //LOOP Step 3: fill in the byte array with data from StringBuffer


    for (int i = 0; i < fileDataString.length(); i++) 
    
         j = i + (partCurrentLoop - 1) * BYTES_PER_LOOP;
         c = fileDataString.charAt(i);              
         fileBytes[j] = (byte) c;   
    
    c=0;
    j=0;
    i=0;

    //LOOP Step 4: Send the email if the byte array is full with a new HttpComm Thread

    if ((fileCurrentLoop % loopsPerHttpComm == 0
            || fileCurrentLoop == fileTotalLoops) && checkHttpCommStatus()) 


        // update partName and httpCommStatus
        String partName = fileName + " .part " + partCurrentNumber;             

        httpCommStatus = HTTP_RUNNING;

        if (fileCurrentLoop == fileTotalLoops)         // FILE_END                 
            debug("New HttpComm Thread: FILE END"); 

            httpCommUpdateBytes(fileBytes.length);//<===================remove
            httpCommSucceeded();//<====================================remove



    /*new Thread(new HttpFileEnd(this, fileBytes, toAddress, fromAddress, fromName, digidownMAC,    partName, fileName, fileSize, digidownSoftwareVersion, partCurrentNumber, //<===============uncomment
                    partTotalNumber, DigidownApp.textObject.getActiveLanguage())).start();*/


         else                                     // FILE_PART


            //debug("Step 5");//<--------------------------------------------------------------------------------<-remove
        debug("New HttpComm Thread: FILE PART: " + partName);
        debug(">>>>>SEEEENDIIIING!<<<<<<<<");//<===========remove
        httpCommUpdateBytes(fileBytes.length);//<================remove
        httpCommSucceeded();//<==============================remove

/*new Thread(new HttpFilePart(this, fileBytes, toAddress, fromAddress, fromName,//<===============uncomment
                    digidownMAC, partName, fileSize, digidownSoftwareVersion,
                    partCurrentNumber, DigidownApp.textObject.getActiveLanguage())).start();*/  


    // Updating the new partTotalLoops
    if (partCurrentNumber == partTotalNumber)
partTotalLoops = fileTotalLoops - (loopsPerHttpComm * (partCurrentNumber - 1));             
             else partTotalLoops = loopsPerHttpComm;


            partCurrentNumber++;
            partCurrentLoop = 0;
        
        fileBytesIsEmpty = true;
        

    // Leave the loop if failed 
    if (!errorHandlerActivated) 

        if (fileCurrentLoop < fileTotalLoops)
        

        try
        bluetoothiostream.getFileBytes();//-throws null pointer exception !
        catch(RuntimeException  ea)debug("Wammaaa!!! " + ea.toString());
                      ea.printStackTrace();

        
        else if(fileCurrentLoop == fileTotalLoops && checkHttpCommStatus())
                       bluetoothIOStream.getFileEnd(); 
    
    



    catch(RuntimeException e1)
    
    Alert alert = new Alert("Fckn error!", e1.toString(), null, null);
    alert.setTimeout(Alert.FOREVER);
    debug("Error:");
    System.err.println();
    e1.printStackTrace();
    //throw e1;

    

..以及未混淆应用程序的堆栈跟踪;这次是空指针异常之后 // Leave the loop if failed:

02:57:382 TSKR. Loop 972 of 1349
02:57:383 BIOS. Rec 978
02:57:588 TSKR. Loop 973 of 1349
02:57:590 BIOS. Rec 979
02:57:815 TSKR. Wammaaa!!! java.lang.NullPointerException:   0
java.lang.NullPointerException:   0
 - java.lang.String.<init>(), bci=6
 - net.digidown.m.digidown.bluetooth.BluetoothIOStream.readLineAsString(), bci=9
 - net.digidown.m.digidown.bluetooth.BluetoothIOStream.getVariable(), bci=844
 - net.digidown.m.digidown.bluetooth.BluetoothIOStream.getFileBytes(), bci=3
 - net.digidown.m.digidown.TaskRunner.bluetoothFileProcessBytes(), bci=430
 - net.digidown.m.digidown.bluetooth.BluetoothIOStream.getVariable(), bci=857
 - net.digidown.m.digidown.bluetooth.BluetoothIOStream.getFileBytes(), bci=3
 - net.digidown.m.digidown.TaskRunner.bluetoothFileProcessBytes(), bci=430
 - net.digidown.m.digidown.bluetooth.BluetoothIOStream.getVariable(), bci=857
 - net.digidown.m.digidown.bluetooth.BluetoothIOStream.getFileBytes(), bci=3
 - net.digidown.m.digidown.TaskRunner.bluetoothFileProcessBytes(), bci=430
 - net.digidown.m.digidown.bluetooth.BluetoothIOStream.getVariable(), bci=857
 - net.digidown.m.digidown.bluetooth.BluetoothIOStream.getFileBytes(), bci=3
 - net.digidown.m.digidown.TaskRunner.bluetoothFileProcessBytes(), bci=430
 - net.digidown.m.digidown.bluetooth.BluetoothIOStream.getVariable(), bci=857

这样过了一会儿,然后..:

 - net.digidown.m.digidown.TaskRunner.bluetoothDoCommand_file(), bci=227
 - net.digidown.m.digidown.bluetooth.BluetoothIOStream.getVariable(), bci=829
 - net.digidown.m.digidown.bluetooth.BluetoothIOStream.getFileSettings(), bci=9
 - net.digidown.m.digidown.TaskRunner.bluetoothTask(), bci=90
 - net.digidown.m.digidown.bluetooth.BluetoothIOStream.getVariable(), bci=513
 - net.digidown.m.digidown.bluetooth.BluetoothIOStream.getTask(), bci=2
 - net.digidown.m.digidown.TaskRunner.bluetoothTask(), bci=172
 - net.digidown.m.digidown.bluetooth.BluetoothIOStream.getVariable(), bci=513
 - net.digidown.m.digidown.bluetooth.BluetoothIOStream.getTask(), bci=2
 - net.digidown.m.digidown.TaskRunner.bluetoothConnected(), bci=89
 - net.digidown.m.digidown.bluetooth.BluetoothIOStream.getVariable(), bci=444
 - net.digidown.m.digidown.bluetooth.BluetoothIOStream.getVariable(), bci=426
 - net.digidown.m.digidown.bluetooth.BluetoothIOStream.run(), bci=366
 - java.lang.Thread.run(), bci=11
03:01:211 TSKR. Finished Task
03:01:212 BIOS. Rec 6
03:01:356 BIOS. task = >
03:01:357 TSKR. :: Got Task: (0x3e)
03:01:358 TSKR.  
03:01:359 TSKR. ERROR HANDLER: 116 - Bluetooth communication error
03:01:389 BIOS. Initiated
03:01:389 BIOS. About to read
03:01:394 BIOS. Phone(InitiateDigidownError) received: '0x3e 0xea Data CK'
03:01:397 BIOS. About to writeLine 'error' 
03:01:468 BIOS. quitStatus = QUIT_STATUS

【问题讨论】:

对不起...我添加了 soem 代码 你的fileDataString是如何初始化的? public static StringBuffer fileDataString = null; 编辑此问题,以便对有相同混淆问题的其他人有用。然后给我们未混淆的堆栈跟踪,以便我们帮助您解决问题。 谢谢!我已经刷新了代码并添加了未混淆应用的堆栈跟踪 【参考方案1】:

您的问题似乎是混淆了。

您的 Eclipse 应用程序的构建过程可能会使用 proguard 之类的工具来提高性能并减小将在现场部署的应用程序 .jar 文件的大小。

混淆的作用之一是将类和方法名称重写为更小的名称,因此堆栈跟踪的最后 3 行完全难以理解。

您需要生成一个未混淆的 .jar 文件,以便在您想要调试应用程序时使用。 (至少在您发现仅在应用程序的混淆版本上发生的问题之前。它会发生)

Eclipse 应该允许您通过修改项目属性来关闭混淆(或将其降低到最低级别)。如果做不到这一点,手动和临时破解用于构建 .jar 文件的 ant .xml 文件就可以解决问题。

混淆参数应该包含您的 MIDlet 类的名称,这样它的 startApp() 方法就不会被重命名。

【讨论】:

我已经尝试创建未混淆的包,现在我有了一些信息。但仍然无法理解什么是 java.lang.String.(),bci=6。同样在出现错误后,在堆栈跟踪中我可以看到三个函数重复了天知道多少次...... 大概是字节码索引(字节码就是java编译的.class文件里面的东西)【参考方案2】:

您的问题可以通过两种方式解决:

    不混淆运行您的应用程序。所以输出会显示准确的方法名称。 将System.out.println('method_name::sample_tag') 放入您的方法和行中,说明问题可能来自于它们。然后在输出中你可以跟踪你的执行,你可以找到问题发生的点。

【讨论】:

谢谢!抱歉,我不熟悉 java - 什么是示例标签? sample_tag 只是一个标签(或评论),您可以通过在输出中查看跟踪来查找跟踪。 (你可以选择任何你想要的)

以上是关于J2ME 混淆的应用程序堆栈跟踪的主要内容,如果未能解决你的问题,请参考以下文章

dexguard 混淆问题

在没有混淆的情况下使用 Proguard 和 Android

如何准确解码 ProGuard 的混淆代码?

Google Play 控制台堆栈跟踪

<OR> 在 Proguard 去混淆跟踪中是啥意思?

Google Play 崩溃跟踪去混淆