在用eclipse实现NDK调试时遇到了一些问题,现在做一些总结。
1. Method ‘NewStringUTF’ could not be resolved
- CDT的bug,可以通过设置去除检查机制:
- 不过这样会去除所有的方法检查,并不是一个好的解决办法。
- 参考http://blog.csdn.net/brokge/article/details/39929525
2. Avoid hardcoding the debug mode
- 也是通过去掉检查机制解决的,具体请参考如下文章http://jingyan.baidu.com/article/636f38bb217a83d6b84610cd.html
- 也可以直接通过在工程根目录下的lint.xml中写入:
<?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)
这句,而/data,/data/data和/data/data/$PACKAGE_NAME
return -1;
每个路径均不能对其他用户具有读写权限才可以。根据这些限制对相应路径做修改即可。
我的手机出现问题的原因是/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