用eclipse实现NDK调试常见问题总结

在用eclipse实现NDK调试时遇到了一些问题,现在做一些总结。

1. Method ‘NewStringUTF’ could not be resolved

2. Avoid hardcoding the debug mode

<?xml version="1.0" encoding="UTF-8"?>
<lint>
    <issue id="HardcodedDebugMode">
        <ignore path="AndroidManifest.xml" />
    </issue>
</lint>

3. ERROR: Could not extract package’s data directory. Are you sure that your installed application is debuggable?

3.1 ndk-gdb.sh脚本

读ndk-gdb.sh脚本,可知上述错误是由以下这段代码引起的:

adb_var_shell2 DATA_DIR run-as $PACKAGE_NAME /system/bin/sh -c pwd
if [ $? != 0 -o -z "$DATA_DIR" ] ; then
    echo "ERROR: Could not extract package's data directory. Are you sure that"
    echo "       your installed application is debuggable?"
    exit 1
fi

其中$PACKAGE_NAME就是所要调试应用的app的包名。
run-as $PACKAGE_NAME的原理大概就是获取该app的权限。
在adb shell中执行run-as $PACKAGE_NAME会得到如下信息:

Package $PACKAGE_NAME has corrupt installation

3.2 run-as.c源码

阅读run-as.c源码

    /* check that the data directory path is valid */
    if (check_data_path(info.dataDir, info.uid) < 0) {
        panic("Package '%s' has corrupt installation\n", pkgname);
        return 1;
    }

3.3 check_data_path()及check_directory_ownership()

check_data_path()方法定义如下:

/* This function is used to check the data directory path for safety.
 * We check that every sub-directory is owned by the 'system' user
 * and exists and is not a symlink. We also check that the full directory
 * path is properly owned by the user ID.
 *
 * Return 0 on success, -1 on error.
 */
int
check_data_path(const char* dataPath, uid_t  uid)
{
    int  nn;

    /* the path should be absolute */
    if (dataPath[0] != '/') {
        errno = EINVAL;
        return -1;
    }

    /* look for all sub-paths, we do that by finding
     * directory separators in the input path and
     * checking each sub-path independently
     */
    for (nn = 1; dataPath[nn] != '\0'; nn++)
    {
        char subpath[PATH_MAX];

        /* skip non-separator characters */
        if (dataPath[nn] != '/')
            continue;

        /* handle trailing separator case */
        if (dataPath[nn+1] == '\0') {
            break;
        }

        /* found a separator, check that dataPath is not too long. */
        if (nn >= (int)(sizeof subpath)) {
            errno = EINVAL;
            return -1;
        }

        /* reject any '..' subpath */
        if (nn >= 3               &&
            dataPath[nn-3] == '/' &&
            dataPath[nn-2] == '.' &&
            dataPath[nn-1] == '.') {
            errno = EINVAL;
            return -1;
        }

        /* copy to 'subpath', then check ownership */
        memcpy(subpath, dataPath, nn);
        subpath[nn] = '\0';

        if (check_directory_ownership(subpath, AID_SYSTEM) < 0)
            return -1;
    }

    /* All sub-paths were checked, now verify that the full data
     * directory is owned by the application uid
     */
    if (check_directory_ownership(dataPath, uid) < 0)
        return -1;

    /* all clear */
    return 0;
}

大概意思就是对/data,/data/data/,及/data/data/$PACKAGE_NAME这几个路径调用 check_directory_ownership()方法。

/* Check that a given directory:
 * - exists
 * - is owned by a given uid/gid
 * - is a real directory, not a symlink
 * - isn't readable or writable by others
 *
 * Return 0 on success, or -1 on error.
 * errno is set to EINVAL in case of failed check.
 */
static int
check_directory_ownership(const char* path, uid_t uid)
{
    int ret;
    struct stat st;

    do {
        ret = lstat(path, &st);
    } while (ret < 0 && errno == EINTR);

    if (ret < 0)
        return -1;

    /* must be a real directory, not a symlink */
    if (!S_ISDIR(st.st_mode))
        goto BAD;

    /* must be owned by specific uid/gid */
    if (st.st_uid != uid || st.st_gid != uid)
        goto BAD;

    /* must not be readable or writable by others */
    if ((st.st_mode & (S_IROTH|S_IWOTH)) != 0)
        goto BAD;

    /* everything ok */
    return 0;

BAD:
    errno = EINVAL;
    return -1;
}

3.4 总结

结合check_data_path()方法,可知/data和/data/data两个路径,必须为system所有,根据if (check_directory_ownership(subpath, AID_SYSTEM) < 0)
return -1;
这句,而/data,/data/data和/data/data/$PACKAGE_NAME
每个路径均不能对其他用户具有读写权限才可以。根据这些限制对相应路径做修改即可。
我的手机出现问题的原因是/data路径权限是
这里写图片描述
于是执行chmod 771 /data之后,再次执行ndk-gdb就成功了。

参考http://www.cnblogs.com/dyingbleed/archive/2012/10/07/2713991.html

4.执行ndk-gdb时,报jdb找不到

在执行ndk-gdb时加上-nowait参数
参考http://blog.csdn.net/atlanticevix/article/details/45028797

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值