blog of faywong

love coding, love life


  • 首页

  • 关于

  • 归档

  • 标签

android studio + jdk7 的bug

发表于 2016-07-25 |

最近换了 mac book pro,重新安装 jdk 时默认选择了 jdk 8,结果下载 android studio 2.1.2 后没法启动。显示如下 crash 信息:

java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.ide.Bootstrap.main(Bootstrap.java:39)
at com.intellij.idea.Main.main(Main.java:103)
Caused by: java.lang.UnsatisfiedLinkError: /Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/jre/lib/lwawt/liblwawt.dylib: dlopen(/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/jre/lib/lwawt/liblwawt.dylib, 1): Library not loaded: @rpath/libosxapp.dylib
Referenced from: /Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/jre/lib/lwawt/liblwawt.dylib
Reason: image not found

后来 google 之,找到一个简单的解决方案(rpath设置不全的原因):

cd /Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/jre/lib/
sudo cp -rf libosxapp.dylib lwawt/

__isnanf引发的血案

发表于 2016-07-18 |

最近遇到了4.x版本 android 上由__isnanf引发的血案,过程就不表了。典型出错日志(4.2.2):

07-18 11:58:20.445 W/ExceptionHandler(15303): Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: soinfo_relocate(linker.cpp:975): cannot locate symbol "__isnanf" referenced by "libmylibrary.so"...

在4.2.2版本的 bionic c 中:

#define isnan(x) \
((sizeof (x) == sizeof (float)) ? isnanf(x) \
: (sizeof (x) == sizeof (double)) ? isnan(x) \
: __isnanl(x))

在后来的版本中,以5.1.1为例,它变成了:

#define isnan(x) \
((sizeof (x) == sizeof (float)) ? __isnanf(x) \
: (sizeof (x) == sizeof (double)) ? isnan(x) \
: __isnanl(x))

我们看下 ndk 中的头文件(以r10e)为例: platform-21 中使用的是 __isnanf,platform-21 以下版本的是 isnanf。

有此可见在低版本的 android 上 __isnanf 不是一定存在的,使用它是不安全的,同时由于 ndk 的不同版本(有些版本有bug,推荐使用 r10e )所包含的 libm.so 并没有与具体的 platform上的 libm.so 保持一致,在链接时并不能发现这一问题。所以针对这个问题,有两个方面要注意:

1) 编译完动态库之后用如下命令查看下动态符号表,确认是否引用了 __isnanf 符号:

arm-linux-androideabi-objdump -T {your_library}

2)如果你觉得1) 这种方式麻烦,你可以采用如下方式将 isnan 转为安全的 __builtin_isnan

#include <math.h>
+#undef isnan
+#define isnan(x) __builtin_isnan(x)

在调查以上问题时,还 get 到了一个很偏门的 c 语言小知识:
在一些 libc 头文件会以如下方式(函数名外边套一对圆括号)声明函数:

int (isnan)(double) __NDK_FPABI_MATH__ __pure2;

其目的在于抑制宏替换,示例如下:

/* the macro */
#define isdigit(c) ...
/* the function */
int (isdigit)(int c) /* avoid the macro through the use of parentheses */
{
return isdigit(c); /* use the macro */
}

机理请见下文:

7.1.4 Use of library functions

Any function declared in a header may be additionally implemented as a function-like macro defined in the header, so if a library function is declared explicitly when its header is included, one of the techniques shown below can be used to ensure the declaration is not affected by such a macro. Any macro definition of a function can be suppressed locally by enclosing the name of the function in parentheses, because the name is then not followed by the left parenthesis that indicates expansion of a macro function name. For the same syntactic reason, it is permitted to take the address of a library function even if it is also defined as a macro.

git自动补全

发表于 2016-07-11 |

为 git 添加自动补全可以为平时的开发工作提升很多效率。而其方法也非常容易:

  1. 下载 git-completion 脚本

    wget https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash
  2. 配置自动加载以上脚本
    若期望整个系统生效,则在 /etc/profile 中(若为单个用户,则在 ~/.bashrc 中)添加:

    source {git-completion.bash}
1…45
faywong

faywong

blog of faywong, faywong

43 日志
16 标签
© 2017 faywong
由 Hexo 强力驱动
主题 - NexT.Muse