Chinaunix首页 | 论坛 | 博客
  • 博客访问: 280003
  • 博文数量: 95
  • 博客积分: 2047
  • 博客等级: 大尉
  • 技术积分: 1022
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-14 16:18
文章分类

全部博文(95)

文章存档

2013年(1)

2011年(94)

我的朋友

分类: 嵌入式

2011-08-30 22:54:27

在调试Wifi时,一旦开始搜索Wifi,系统就会down掉,打开debug信息,发现如下内容

I/ActivityManager(  825): Starting activity: Intent { act=android.intent.action.MAIN cmp=com.android.settings/.wifi.WifiSettings }
D/dalvikvm(  893): GC freed 3772 objects / 231344 bytes in 79ms
D/SettingsWifiEnabler(  893): Received wifi state changed from Enabling to Enabled
I/ActivityManager(  825): Displayed activity com.android.settings/.wifi.WifiSettings: 707 ms (total 707 ms)
I/wpa_supplicant(  966): CTRL-EVENT-SCAN-RESULTS  Ready
V/WifiStateTracker(  825): Connection to supplicant established, state=SCANNING
D/NetworkStateTracker(  825): setDetailed state, old =IDLE and new state=SCANNING
D/ConnectivityService(  825): ConnectivityChange for WIFI: DISCONNECTED/SCANNING
D/DataConnectionTracker(  875): enableApnType(default), isApnTypeActive = false and state = IDLE
I/wpa_supplicant(  966): CTRL-EVENT-SCAN-RESULTS  Ready
W/dalvikvm(  825): JNI WARNING: illegal start byte 0xb3
W/dalvikvm(  825):              string: 'bssid / frequency / signal level / flags / ssid
W/dalvikvm(  825): 00:10:18:00:00:b6    2437    171                     wireless
W/dalvikvm(  825): 02:2c:7c:04:c7:01    2437    169     [IBSS]          WZD-成人教育学院'
W/dalvikvm(  825):              in Landroid/net/wifi/WifiNative;.scanResultsCommand ()Ljava/lang/String; (NewStringUTF)
I/dalvikvm(  825): "Binder Thread #5" prio=5 tid=63 NATIVE
I/dalvikvm(  825):   | group="main" sCount=0 dsCount=0 s=N obj=0x43a5ea30 self=0x3b1178
I/dalvikvm(  825):   | sysTid=911 nice=0 sched=0/0 cgrp=unknown handle=3871032
I/dalvikvm(  825):   at android.net.wifi.WifiNative.scanResultsCommand(Native Method)
I/dalvikvm(  825):   at com.android.server.WifiService.getScanResults(WifiService.java:1050)
I/dalvikvm(  825):   at android.net.wifi.IWifiManager$Stub.onTransact(IWifiManager.java:126)
I/dalvikvm(  825):   at android.os.Binder.execTransact(Binder.java:287)
I/dalvikvm(  825):   at dalvik.system.NativeStart.run(Native Method)
I/dalvikvm(  825): 
E/dalvikvm(  825): VM aborting
I/DEBUG   (  811): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   (  811): Build fingerprint: 'ky6410/ky6410/ky6410/:2.1-update1/ECLAIR/eng.kyon.20100609.214617:eng/test-keys'
I/DEBUG   (  811): pid: 825, tid: 911  >>> system_server <<<
I/DEBUG   (  811): signal 11 (SIGSEGV), fault addr deadd00d
I/DEBUG   (  811):  r0 00000328  r1 afe1332d  r2 0000000c  r3 deadd00d
I/DEBUG   (  811):  r4 00000026  r5 47f6ab74  r6 000000c0  r7 fffe6184
I/DEBUG   (  811):  r8 47f6bb90  r9 46215ef8  10 46215ee4  fp 003b1108
I/DEBUG   (  811):  ip ad07f14c  sp 47f6ab18  lr afe142e9  pc ad035006  cpsr 20000030
I/DEBUG   (  811):          #00  pc 00035006  /system/lib/libdvm.so
I/DEBUG   (  811):          #01  pc 00027698  /system/lib/libdvm.so
I/DEBUG   (  811):          #02  pc 00028220  /system/lib/libdvm.so
I/DEBUG   (  811):          #03  pc 00028298  /system/lib/libdvm.so
I/DEBUG   (  811):          #04  pc 0003595a  /system/lib/libandroid_runtime.so
I/DEBUG   (  811):          #05  pc 00035d54  /system/lib/libandroid_runtime.so
I/DEBUG   (  811):          #06  pc 00035d92  /system/lib/libandroid_runtime.so
I/DEBUG   (  811):          #07  pc 0000ef74  /system/lib/libdvm.so
I/DEBUG   (  811):          #08  pc 00037b28  /system/lib/libdvm.so
I/DEBUG   (  811):          #09  pc 000311f2  /system/lib/libdvm.so
I/DEBUG   (  811):          #10  pc 00013c88  /system/lib/libdvm.so
I/DEBUG   (  811):          #11  pc 00019588  /system/lib/libdvm.so
I/DEBUG   (  811):          #12  pc 00018a5c  /system/lib/libdvm.so
I/DEBUG   (  811):          #13  pc 0004d1ee  /system/lib/libdvm.so


具体错误在
W/dalvikvm(  825):              in Landroid/net/wifi/WifiNative;.scanResultsCommand ()Ljava/lang/String; (NewStringUTF)
这句提交了一个illegal的UTF8字符

Google半天,大意为Google的UTF8是经过修改过的,对一些UTF8字符不兼容。
在dalvik/vm/checkjni.c中做判断
/*
 * Verify that "bytes" points to valid "modified UTF-8" data.
 */
static void checkUtfString(JNIEnv* env, const char* bytes, bool nullOk,
    const char* func)
{
    const char* origBytes = bytes;
    if (bytes == NULL) {
        if (!nullOk) {
            LOGW("JNI WARNING: unexpectedly null UTF string\n");
            goto fail;
        }
        return;
    }
    while (*bytes != '\0') {
        u1 utf8 = *(bytes++);
        // Switch on the high four bits.
        switch (utf8 >> 4) {
            case 0x00:
            case 0x01:
            case 0x02:
            case 0x03:
            case 0x04:
            case 0x05:
            case 0x06:
            case 0x07: {
                // Bit pattern 0xxx. No need for any extra bytes.
                break;
            }
            case 0x08:
            case 0x09:
            case 0x0a:
            case 0x0b:
            case 0x0f: {
                /*
                 * Bit pattern 10xx or 1111, which are illegal start bytes.
                 * Note: 1111 is valid for normal UTF-8, but not the
                 * modified UTF-8 used here.
                 */
                LOGW("JNI WARNING: illegal start byte 0x%x\n", utf8);
                goto fail;
            }
            case 0x0e: {
                // Bit pattern 1110, so there are two additional bytes.
                utf8 = *(bytes++);
                if ((utf8 & 0xc0) != 0x80) {
                    LOGW("JNI WARNING: illegal continuation byte 0x%x\n", utf8);
                    goto fail;
                }
                // Fall through to take care of the final byte.
            }
            case 0x0c:
            case 0x0d: {
                // Bit pattern 110x, so there is one additional byte.
                utf8 = *(bytes++);
                if ((utf8 & 0xc0) != 0x80) {
                    LOGW("JNI WARNING: illegal continuation byte 0x%x\n", utf8);
                    goto fail;
                }
                break;
            }
        }
    }
    return;
fail:
    LOGW("             string: '%s'\n", origBytes);
    showLocation(dvmGetCurrentJNIMethod(), func);
    abortMaybe();
}

如果出现非法的UTF8字符就挂掉,这个也太狠了吧。

继续追踪根源,非法UTF8字符提交来自/frameworks/base/core/jni/android_net_wifi_Wifi.cpp的函数
// Send a command to the supplicant, and return the reply as a String
static jstring doStringCommand(JNIEnv *env, const char *cmd)
{
    char reply[4096];

    if (doCommand(cmd, reply, sizeof(reply)) != 0) {
        return env->NewStringUTF(NULL);
    } else {
        return env->NewStringUTF(reply);
    }
}

网上提出的解决方案是将非法头字符修正为“?”,将其他非法字符修正为“0x80”,patch后的函数如下:
// Send a command to the supplicant, and return the reply as a String
static jstring doStringCommand(JNIEnv *env, const char *cmd)
{
    char reply[4096];
char* bytes;
    if (doCommand(cmd, reply, sizeof(reply)) != 0) {
        return env->NewStringUTF(NULL);
    } else {
        // Make sure reply only contains valid UTF-8 Characters 
        // This is borrowed from CheckJni.c 
        bytes = reply; 
        while (*bytes != '\0') 
            char utf8 = *bytes; 
            switch (utf8 >> 4) { 
            case 0x00: 
            case 0x01: 
            case 0x02: 
            case 0x03: 
            case 0x04: 
            case 0x05: 
            case 0x06: 
            case 0x07:
  { 
                // Bit pattern 0xxx. No need for any extra bytes. 
                break; 
            } 
            case 0x08:
            case 0x09: 
            case 0x0a:
            case 0x0b:
            case 0x0f: 
 { 
                /* 
                 * Bit pattern 10xx or 1111, which are illegal start bytes. 
                 * Note: 1111 is valid for normal UTF-8, but not the 
                 * modified UTF-8 used here. +                 */ 
                LOGW("JNI WARNING: illegal start byte 0x%x, changing to '?'\n", utf8); 
//return env->NewStringUTF("AP"); //modify by rockie
                *bytes = '?'; 
            } 
            case 0x0e: { 
                // Bit pattern 1110, so there are two additional bytes. 
                utf8 = *(++bytes); 
                if ((utf8 & 0xc0) != 0x80) { 
                    LOGW("JNI WARNING: illegal continuation byte 0x%x, changing to 0x80.\n", utf8); 
                    *bytes = 0x80; 
               
                // Fall through to take care of the final byte. 
           
            case 0x0c: 
            case 0x0d: { 
                // Bit pattern 110x, so there is one additional byte. 
                utf8 = *(++bytes); 
                if ((utf8 & 0xc0) != 0x80) { 

                    LOGW("JNI WARNING: illegal continuation byte 0x%x, changing to 0x80.\n", utf8); 
                    *bytes = 0x80; 
               
                break; 
           

            } 
            bytes++; 
        } 

        return env->NewStringUTF(reply);
    }
}

非常不解的是,patch后还是会有漏网的错误字符被提交到checkjni.c,导致系统挂掉
D/wpa_supplicant(  976): Setting scan request: 5 sec 0 usec
W/wifi    (  826): JNI WARNING: illegal start byte 0xb3, changing to '?'
W/wifi    (  826): JNI WARNING: illegal continuation byte 0xc9, changing to 0x80.
W/wifi    (  826): JNI WARNING: illegal continuation byte 0xc8, changing to 0x80.
W/wifi    (  826): JNI WARNING: illegal continuation byte 0xd3, changing to 0x80.
W/wifi    (  826): JNI WARNING: illegal start byte 0xfd, changing to '?'
W/wifi    (  826): JNI WARNING: illegal continuation byte 0xd1, changing to 0x80.
W/dalvikvm(  826): JNI WARNING by rockie : illegal start byte 0x80, changing to '?'
W/dalvikvm(  826): JNI WARNING: illegal continuation byte 0xcb
W/dalvikvm(  826):              string: 'bssid / frequency / signal level / flags / ssid
W/dalvikvm(  826): 00:21:91:6f:f1:f2    2437    205                     dlink
W/dalvikvm(  826): 00:10:18:00:00:b6    2437    175                     wireless
W/dalvikvm(  826): 02:2c:7c:04:c7:01    2437    169     [IBSS]          WZD-?
阅读(1355) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~