运行jni时 log打印提示Library 'lib_glossary.so'yasm not foundd 求原因,求解答

android - JNI- java.lang.UnsatisfiedLinkError: Native method not found - Stack Overflow
to customize your list.
Join the Stack Overflow Community
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.
J it only takes a minute:
I'm developing an Android project using OpenCV. Some of the methods do not have Java version, so I have to use NDK to use them in my project.
This is my first time using NDK, so after searching for some examples, I wrote my code, run it on my device, and received error message below:
07-04 10:26:19.555
/com.example.MyTest E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.UnsatisfiedLinkError: Native method not found: com.example.MyTest.JNIlib.readImg:()I
at com.example.MyTest.JNIlib.readImg(Native Method)
at com.example.MyTest.MyActivity$2.onClick(MyActivity.java:60)
at android.view.View.performClick(View.java:4211)
at android.view.View$PerformClick.run(View.java:17267)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4898)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
at dalvik.system.NativeStart.main(Native Method)
I regenerated .so files for several times, and check the naming for jni functions. I also added 'extern "C"' wrappers to jni functions. But none of those solutions worked.
Notice: I always use Intellij Idea to develop JAVA programs, and since Idea doesn't support NDK, and I have to use Eclipse to get to NDK, so...this is also the first time I use Eclipse. I could have made a lot of silly mistakes. lol
Below are my c++ codes and makefile.
LocalMain.cpp
#include &stdio.h&
#include &iostream&
#include &opencv2/nonfree/nonfree.hpp&
#include &opencv2/highgui/highgui.hpp&
#include &opencv2/nonfree/features2d.hpp&
#include &opencv2/opencv.hpp&
#include &jni.h&
#include &android/log.h&
#include "LocalFeature.h"
int readImg()
/* do something*/
// JNI interface functions, be careful about the naming.
extern "C"
JNIEXPORT jint JNICALL Java_com_example_MyTest_JNIlib_readImg(JNIEnv * env, jobject obj);
JNIEXPORT jint JNICALL Java_com_example_MyTest_JNIlib_readImg(JNIEnv * env, jobject obj)
return (jint)readImg();
LocalFeatures.h and LocalFeatures.cpp are not shown, but I'm sure the problem is not with them.
Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE
:= nonfree_prebuilt
LOCAL_SRC_FILES := libnonfree.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE
:= opencv_java_prebuilt
LOCAL_SRC_FILES := libopencv_java.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
# Modify LOCAL_C_INCLUDES with your path to OpenCV for Android.
LOCAL_C_INCLUDES:= E:/Java/libs/OpenCV-2.4.9-android-sdk/sdk/native/jni/include
LOCAL_MODULE
:= mytest_lib
LOCAL_CFLAGS
:= -Werror -O3 -ffast-math
LOCAL_LDLIBS
+= -llog -ldl
LOCAL_SHARED_LIBRARIES := nonfree_prebuilt opencv_java_prebuilt
LOCAL_SRC_FILES := LocalMain.cpp \
LocalFeature.h \
LocalFeature.cpp
include $(BUILD_SHARED_LIBRARY)
Those .cpp files and .mk files are in an Eclipse project. libmytest_lib.so, libopencv_java.so, libnonfree.so can be correctly generated.
The following .java files are in an Intellij Idea project. I have copied these .so files to \lib in the Idea project.
JNIlib.java
public class JNIlib {
// Load necessary libraries.
System.loadLibrary("opencv_java");
System.loadLibrary("nonfree");
System.loadLibrary("mytest_lib");
catch( UnsatisfiedLinkError e )
System.err.println("Native code library error.\n");
public static native int readImg();
Part of MainActivity.java
public class MyActivity extends Activity implements CameraBridgeViewBase.CvCameraViewListener2{
public View.OnClickListener onClickListener = new View.OnClickListener() {
public void onClick(View v) {
JNIlib.readImg();
/*Other irrevelant code*/
Thanks a lot!
After following JonesV's advice, I removed static from my code. But after that, the problem still exists.
Finally I debugged my my program, and when running to this line:
System.loadLibrary("opencv_java");
The program threw an error, instead of running normally as I thought. REALLY STUPID MISTAKE :&
Now that I found an error I'd never noticed before.
java.lang.UnsatisfiedLinkError: Couldn't load opencv_java: findLibrary returned null
Which means, NO LIBS ARE LOADED. So I checked my project structure, and found that I put my .so files in libs/ folder, instead of libs/armeabi/ folder.
And the solution is found here:
by user1647750
Remove static from:
public static native int readImg();
i.e. write it like this:
public native int readImg();
If you really want your readImg() method to be static, you should declare the JNI method as follows (with jclass instead of jobject):
JNIEXPORT jint JNICALL Java_com_example_MyTest_JNIlib_readImg(JNIEnv * env, jclass obj);
3,57152153
Your Answer
Sign up or
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Post as a guest
By posting your answer, you agree to the
Not the answer you're looking for?
Browse other questions tagged
Stack Overflow works best with JavaScript enabledProbably many people have had after installing VC 6.0 click &Compile& or &Build& appears after &Compiling ..., Error spawning cl.exe& error message to the depressed too. Many people's choice is reload, in fact, in many cases
1. In the &My Computer - Properties - Advanced - Environment Variables&, add the following variables: INCLUDE D: \ Program Files \ Microsoft Visual Studio \ VC98 \ Include LIB D: \ Program Files \ Microsoft Visual Studio \ VC98 \ Lib PATH X: \ P
Environment: windows already installed VS2005 1, set the environment variable Objective: cmd window automatically identify cl command settings: in the &My Computer& -& Properties -& Advanced -& Environment Variables in INCLUDE D: \ Prog
Many people may have after installing VC 6.0 over click &Compile& or &Build& appears after &Compiling ..., Error spawning cl.exe& error message to the depressed too. Many people's choice is reloading, in fact, in many cases t
1, add the vc's bin directory to path: PATH = D: \ Program Files \ Microsoft Visual Studio 8 \ VC \% PATH% 2, add the environment variable INCLUDE = D: \ Program Files \ Microsoft Visual Studio 8 \ VC \ PlatformSDK \ I D: \ Program Files
Clozure CL 网站 : /ccl Clozure CL,曾用名 OpenMCL,也叫CCL.它是一款高性能的开源 Common Lisp 实现, 可运行于以下平台: Mac OS X 10.4 and later (PowerPC and x86) Linux (PowerPC and x86) FreeBSD 6.x and later (x86) Solaris (x86) Microsoft Windows XP and later (
方法1: 启动VC时不要用图形界面,通过在命令提示符下输入:Msdev /useenv运行(注意啦/前面有个空格).它会强制使系统环境变量全高设置成正确值.而且,只需要使用一次这样的方式运行VC,以后再次通过双击图标的方式启动也不会有问题. 方法2: 使用你的VC安装盘修复一下. 方法3: 在VC中点击&Tools&-&&Option&-&&Directories&,发现路径有误,重新设置&Excutable Fils,In
看了dodolook写的我也要学C语言-第二章:第一个C程序的编译初解,也想试试用CL编译器手动编译C程序. 电脑上装了VS2010,在Microsoft Visual Studio 10.0\VC\bin中找到cl.exe文件.于是,在命令行中进入这个目录,运行cl,却出现错误提示: cl.exe - System Error --------------------------- The program can't start because mspdb100.dll is missing
CL.exe 是控制 Microsoft C 和 C++ 编译器与链接器的 32 位工具.编译器产生通用对象文件格式 (COFF) 对象 (.obj) 文件.链接器产生可执行文件 (.exe) 或动态链接库文件 (DLL). 注意,所有编译器选项都区分大小写. 用法如下: CL [option...] file... [option | file]... [lib...] [@command-file] [/link link-opt...] option : 一个或多个 CL 选项.请注意,所
编译 Clozure CL 的 Mac IDE 版,超级简单 打开 CCL 的文档,看了一下,就几步,描述如下: 5.2. Building the IDE Building the Clozure CL IDE is now a very simple process. In a shell session, cd to the ccl directory. Run ccl from the shell. The easiest way to do this is generally to e
CLozure CL 多线程函数使用实例 一.简单介绍 Common Lisp 的标准没有对多线程的描述,因此各种 CL 实现都给出了自己的多线程功能函数,具体细节有所不同,这里大致讲解一下 Clozure CL 的多线程函数的简单用法(参照 CCL 的描述文档中多线程部分 第7章 Programming with threads). 我在阅读CCL文档时被搞晕了,发现找不到线程对象作为参数的正确写法,后来经过 cn-lisp 的朋友指点,才发现不存在所谓的正确写法,只能把线程对象绑定到全局变量
使用之前 打开控制台(CTRL+R&cmd):键入cl回车:如果出现如下提示: 'cl' 不是内部或外部命令,也不是可运行的程序或批处理文件. 则说明VS没有安装或者环境变量设置不正确,可以按照如下步骤设置: 1. 确保已经安装VS,并在控制台 中键入set 检查是否有类似如下格式的环境变量VSXXCOMNTOOLS VS90COMNTOOLS=D:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\ 其中XX与VS版本有关: a)
自己的emacs配置在windows下使用已经很好了,也总结了很多脚本,最近在运行lisp时出现问题,我用的是sbcl和Clozure CL.这两个都是最优秀的开源lisp实现之一.我的配置文件都在我的git仓库目录,这样方便和其他机器上的同步,同样也把quicklisp安装到git仓库,这样不用在其他电脑用时需求下载相应 的库.我的配置文件在/wuhen/emacs-config. 测试LISP步骤: 一,SBCL: 1),打开emacs-cl
使用 Clozure CL 在 Cocoa 窗口组件中实现显示中文字符串的简单方法 目录 0 概述 1 Objective-C 和 Lisp 的不同方法 2 英文标题代码示例 3 中文标题代码示例 0 概述 我们知道, 在 Cocoa 中提供了两种字符串类: NSString 和 NSMutableString, 前者用于处理内容不变, 固定的字符串, 比如窗口标题; 后者用于处理内容可变的字符串, 当然后者也可以用于前者的使用场合. 因为后者 NSMutableString 类是在继承 NSS
General problems of the project configuration, you can try to disable optimization.
This time we prepared to look Heritrix, to read up on the source code, and then some extension to their own needs. Heritrix profile today to eclipse occurs when the resource file not found exception. Exception in thread &main& java.io.IOExceptio
[Img] http://b57.photo./http_imgload.cgi?/rurl4_b=09fb404eaf2b8b76ed5222dfd893ced919ca5b015d5ffd1397dbb5fbb0f6fc85a48ea62aef6dbb4aa7d9a179aa657349e&a=58&b=57 [/ img
apply / funcall function & rest args + apply can accept multiple parameters, but the last argument must be a list, where each element is a function of the parameters funcall can accept multiple parameters, are the function of the parameters for the l
root @ macopad-desktop: ~ / workspace / sina / www / study # php k.php PHP Deprecated: Comments starting with '#' are deprecated in / etc/php5/cli/conf.d/idn.ini on line 1 in Unknown on line 0 PHP Deprecated: Comments starting with '#' are deprecated
CL-USER& (load &http://beta.quicklisp.org/quicklisp.lisp&) ==== quicklisp quickstart loaded ==== To continue with installation, evaluate: (quicklisp-quickstart:install) For installation options, evaluate: (quicklisp-quickstart:help) &htt
svn: OPTIONS of 'http://example.org/example_repo': Could not read status line: connection was closed by server (http://example.org) 主要原因是:和Cisco Anyconnect Client's的Web Security模块冲突 解决方法: 1. 移除 cisco anyconnect 2. 重装 anyconnect 但不安装&Web Security&quot
Bluetooth Glossary This article comes from CSDN blog, reproduced please indicate source: http://blog.csdn.net/lendalscut/archive//1551805.aspx The following vocabulary tables are the most commonly used Bluetooth technology vocabulary, so th
Opening, or have to talk about ^ and $ that they are separately used to match the beginning and end of the string, the following examples to illustrate separately &^ The&: there must be at the beginning of &The& &of despai
Adobe APIs Mainly includes corelib, mappr, flickr, youtube and encryption library. /wiki/index.php/ActionScript_3:resources:apis:libraries as3awss3lib Amazon S3 interact with ActionScript 3.0 Class Library /
Want to say quickly when finished Today is the Ching Ming Festival, the big holiday, and I basically did not do other. I hope you see the people in this article, you can harvest a little. This is also pleased with my point, my time is not wasted. Thi
Soon to say when finished Today is Ching Ming, the holiday, and I basically did not do other. I hope you see this article for people that can gain you a bit. So pleased that I also, I have not the time to be wasted. It is also a long article smelly a
Character / Significance: For the characters, usually expressed by the literal meaning, pointing out that the next character for special characters, does not explain. For example: / b / matches the characters' b ', preceded by a backslash b, that is,
Bouncy Castle for the Java platform is an open source lightweight cryptography package. It supports a large number of cryptography algorithms, and provide JCE 1.2.1 implementation. Bouncy Castle because it is designed lightweight, so from J2SE 1.4 to
http://blog.csdn.net/wjp/archive//4601103.aspx JAVA_ advanced features (hashCode, clone, comparator, Class reflection, serialization) &script type=&text/javascript&& &/ script& &script type=&text/javascript
import java.io.FileInputS import java.io.InputS import java.sql.C import java.util.ArrayL import java.util.HashM import java.util.L import java.util.M import jxl.C import jxl.CellT import jxl.NumberC im
How to use Reflection in Java http://www.java-tips.org/java-se-tips/java.lang.reflect/how-to-use-reflection-in-java.html Quote Reflection is a powerful approach to analyze the class at runtime. If new classes are added into your application dynamical
import java.io.F import java.io.PrintS import java.lang.reflect.F import java.lang.reflect.M import java.net.MalformedURLE import java.net.URL; import java.net.URLClassL import java.util.L import sun.misc.Launc
WWW is based on Internet as the transmission medium of an application system, WWW-line transmission of the basic unit is the Web page. WWW's work is based on client / server computing model, from the Web browser (client) and Web server (server) const
/ / Programming Example: calculate from the current time 315 days after the date and time, and use &XXXX dated XX on XX years of XX hours: XX minutes: XX seconds& format output. / / Programming Example:
In accordance with the March 15
The first thing we know before the Huffman tree to find out the simple binary tree, it is easy to understand, is a binary tree each node have only two sub-nodes in the tree structure, and also divided into parent node (parent node), the left sub-tree
JNI using the skills bit by bit in this 32-bit Windows platform, Java native methods to achieve provides a useful example of the steps and guidelines. The examples in this article was created using Sun Microsystems's Java Development Kit (JDK) versio
To learn a bit JNI, published an article I did not know what a good selection, and do not know JNI should belong to that area ^ _ ^. 1. About JNI is the Java Native Interface The acronym, which is designed to: The Standard Java class Library may not
public class ParamUtil { private static String DATE_FORMAT_1 = &yyyy-MM-dd&; private static String DATE_FORMAT_2 = &yyyy-MM-dd HH:mm:ss&; private static String DATE_MATCHER_1 = &^\\d{4}(\\-)\\d{1,2}\\1\\d{1,2}$&; private stat
Original: http://zhangjunhd./83 1. What is REST? REST by Roy Fielding in his thesis &Architectural Styles and the Design of Network-based Software Architectures& presented in a term. REST is the English acronym for Repres
12.3.1 The class loading strategy For the system, each application program server, class loading strategy can be set to Single or Multiple. When an application class loader policy set to Single, a single application class loader can load the application s
12.5.2 Step 2: Add an EJB module and tools for JAR Now, to the application program to add an EJB, it also depends VersionChecker JAR file. Here, in the EAR's root directory to add a VersionCheckerV2.jar file. In this JAR file VersionChecker class ret
International domain name: . com (commercial organizations),. net (network service),. org (nonprofit organization) com General on behalf of profit-making institutions, such as corporate, edu, said educational institutions cn is the area code, on beha
Introduction: Class loader (class loader) yes Java (TM) in a very important concept . Class loader responsible loaded Java classes byte code into Java virtual machine. Article first introduced in detail Java class loader basic concepts, including proxy
The encoding of Chinese characters more detailed definition of specifications can refer to: .cn/cjk/ana17.htm Java, an international design /docs/books/tutorial/i18n/index.html Linux internationalization and lo
Apache has Pivot upgraded to top-level project, although the former did not know this project, it seems that there are still promising. I like it, because I FLEX grammar really do not cold, or Java written comfortable. Seems to have few people with t
1 Introduction Java Virtual Machine (JVM) refers to the class loader will be included in the class file loaded into JVM byte code, the And make it a part of the JVM process. JVM Dynamic class loading technology can be dynamically loaded at run time o
/ projects / jquery / lightbox / Border automatically adjust according to picture size frame, and the next one can be on the look, but I have not figure out, save the first. -------------------------------------------------
[Js Effects] instead of a scroll marquee effect of the code as marquee labels caption is now used less and less, so most of rolling results-based approach also use javascript to achieve, and those who are not understand why does not directly friends
/btjxzzy/blog/item/f09f4cd9e9c1ba2e11df9b00.html Question 6: Where can I change the configuration file? You can use a text editor to change the XAMPP various configuration files. These files exist in the following path: Apache basi
Can only enter a number: &^ [0-9 ]*$&。 N bits can only enter the number: &^ \ d (n) $&. Can only enter at least n-bit numbers: &^ \ d (n ,}$&。 Can only enter the m ~ n-bit numbers:. &^ \ d (m, n) $& Enter only the n
Copyright (C) , All Rights Reserved.
版权所有 闽ICP备号
processed in 0.049 (s). 10 q(s)Android&Native/Tombstone&Crash&Log&详细分析[原创]
Android 虽然已经有好几年了,但是NDK的开放速度却非常缓慢,所以目前网络上针对对Android Native
Crash的分析说明还比较少,尤其是非常详细的分析方式更难以查询。因此大部分程序员在遇到难以进行addr2line的crash
log时,会一筹莫展。事实上这份log中的其他部分同样提供了非常丰富的信息可供解读,所以在这里总结一下对在这方面的一些经验,在这里以Android
samples中的hello-jni为参照做了一定的修改产生的crash来进行分析说明。在深入理解错误日志的分析之后,许多难以复制或者几乎不能重现的bug也能够得到有效的解决。以下所有内容为夜莺原创。
内容主要分为一下几个部分:
1.Library Symbols (共享库的符号)
2.Analyze Tools (可用到的分析工具)
3.CrashLog & Header&
4.CrashLog&& Backtrace(For
most crashes)
5.CrashLog&& Registers
6.CrashLog&& Memory
7.CrashLog&& Stack
8.Library Base Address (共享库在内存中基地址)
1.Library Symbols (共享库的符号)
ndk提供了一些工具可以供程序员直接获取到出错的文件,函数以及行数。
但是这部分工具都需要没有去符号的共享库(通常是放在out/target/product/xxx/symbols/system/lib)。而out/target/product/xxx/system/lib中的共享库是去掉了符号的,所以直接从设备上抓下来的lib是不能够通过工具来找到对应的符号(而且没有去symbol的库比去掉的空间占用会大许多)。所以如果想要分析一份native
crash,那么unstripped
lib几乎不可缺少,但是即使是strip过的库也同样会包含少量的symbol。
2.Analyze Tools&
即常用的辅助工具
01&addr2line
&($(ANDROID_NDK)\toolchains\arm-linux-androideabi-4.7\prebuilt\windows\bin)
02&#通过backtrace一栏提供的地址查询对应的符号,可以定位到文件,函数,行数.
addr2line &aCfe libs $(trace_address)
05&ndk-stack
(android-ndk-r8d\ndk-stack)
06&#相当于执行多次addr2line,
可以直接针对一份crash log使用,会输出所有backtrace里地址对应的symbol
ndk-stack &sym $(lib_directory) &dump
$(crash_log_file)
09&objdump
(android-ndk-r8d\toolchains\arm-linux-androideabi-4.7\prebuilt\windows\bin)
10&#Dump the object
file. 通过汇编代码定位错误的原因,大部分复杂的问题可以通过这种方式得到解决。
objdump -S $(objfile) & $(output_file)
3.Crash Log - Header
信息头,包含当前系统版本有关的信息,如果是做平台级的开发,这将有助于定位当前的系统的开发版本。
description: xxxx
4&Hardware:
5&Revision:
6&Bootloader:
Linux version 3.4.5 xxxx
这部分较为容易阅读。所以不再赘述。
4.CrashLog&& Backtrace(For
most crashes)
即最常用的看backtrace部分,backtrace的地址可用addr2line或者ndk-stack查找对应的symbol,非常直观,大多数的crash都能够通过这种方式解决。
01&backtrace:
&pc 00026fbc
&/system/lib/libc.so
&pc 000004cf
&/data/app-lib/com.example.hellojni-1/libhello-jni.so
(Java_com_example_hellojni_HelloJni_stringFromJNI+18)
&/system/lib/libdvm.so
(dvmPlatformInvoke+112)
&/system/lib/libdvm.so (dvmCallJNIMethod(unsigned
int const*, JValue*, Method const*, Thread*)+500)
&/system/lib/libdvm.so
(dvmResolveNativeMethod(unsigned int const*, JValue*, Method
const*, Thread*)+200)
&/system/lib/libdvm.so
&/system/lib/libdvm.so (dvmInterpret(Thread*,
Method const*, JValue*)+180)
&pc 0006175f
&/system/lib/libdvm.so (dvmInvokeMethod(Object*,
Method const*, ArrayObject*, ArrayObject*, ClassObject*,
bool)+374)
&/system/lib/libdvm.so
&/system/lib/libdvm.so
&/system/lib/libdvm.so (dvmInterpret(Thread*,
Method const*, JValue*)+180)
&/system/lib/libdvm.so (dvmCallMethodV(Thread*,
Method const*, Object*, bool, JValue*,
std::__va_list)+272)
&pc 0004a2ed
&/system/lib/libdvm.so
&/system/lib/libandroid_runtime.so
&/system/lib/libandroid_runtime.so
(android::AndroidRuntime::start(char const*, char
const*)+536)
&pc 00000db7
&/system/bin/app_process
&pc 00020ea0 &/system/lib/libc.so
(__libc_init+64)
&pc 00000ae8
&/system/bin/app_process
从上面这份backtrace可以看到包含一个pc地址和后面的symbol。部分错误可以通过只看这里的symbol发现问题所在。而如果想要更准确的定位,则需要借助ndk工具。
1&$addr2line
-aCfe out/target/production/xxx/symbols/system/lib/libhello-jni.so
3&java_com_example_hellojni_HelloJni_stringFromJNI
4&/ANDROID_PRODUCT/hello-jni/jni/hello-jni.c:48
然后再来看看hello-jni.c
17&#include
18&#include
func_a(char *p);
func_b(char *p);
func_a(char *p)
& &const char* A = "AAAAAAAAA";
& &char* a = "dead";
& &memcpy(p, A, strlen(A));
& &memcpy(p, a, strlen(a));
& &p[strlen(a)] = 0;
& &func_b(p);
func_b(char *p)
& &char* b = 0xddeeaadd;
& &memcpy(b, p, strlen(p));
43&jstring
44&Java_com_example_hellojni_HelloJni_stringFromJNI(
JNIEnv* env,
&jobject thiz )
& &char buf[10];
& &func_a(buf);
& &return (*env)-&NewStringUTF(env, "Hello from JNI
可以看到现在只能看到出错在func_a(). 这里面有个比较特别的地方是为什么backtrace
中只有func_a而没有出现func_b.
这是编译器的处理部分,不过多赘述。所以现在只能从backtrace中确认#1是在func_a,然后#0是在libc中的某个函数死掉。其实symbols/system/lib中也包含有libc.so,可以通过addr2line确认是那个函数。而这里调用到libc的只有memcpy,
所以可以基本确定出错在memcpy,但是有三个memcpy,又怎么确定是哪一个呢?(当然,可以通过直接检查代码发现是在func_b里面)
5.CrashLog&&
寄存器信息,可以通过这部分信息基本确定系统为什么会错。
4000, tid: 4000, name: xample.hellojni &
11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr
&r0 ddeeaadd &r1 beab238c
&r5 40e1b760
&r8 beab23a8 &r9 4bdd2c98
&sl 40e1d050 &fp
&sp beab2380 &lr
&pc 400dffbc &cpsr
&6e6a6f6c6c656865
&726f6c6f632f3c64
&3e2d2d206f646f54 &d5
&656d616e20726f6c &d7
& &d10 0000
& &d12 0000
& &d14 0000
& &d16 019e
& &d18 0000
&d19 000000
& &d20 e000
& &d22 0000
&d23 090a0b0c0d0e0f10
& &d24 0003d
&d25 000000
& &d26 0000b7
& &d28 0003d
& &d30 0001
这部分信息展示了出错时的运行状态,
当前中断原因是收到SIGSEGV(通常crash也都是因为收到这个信号,也有少数是因为SIGFPE,即除0操作)。错误码是SEGV_MAPERR,常见的段错误。然后出错地址为ddeeaadd。即第39行的地址0xddeeadd。所以已经可以基本确定和指针b有关。
而代码里面接下来便是memcpy的操作。所以很明显就是在这里的memcpy有问题。
再看r0是ddeeaadd,r1是beab238c,r2是4,其实这三个寄存器刚好代表memcpy的操作参数。目的地址为ddeeaadd,源地址加偏移为beab238c,长度是4。这里有提到beab238c为源地址加偏移,原因的话会在后面解释。
通常我们需要关注的寄存器主要就是r0到pc,下面的32个寄存器的话通常是数据存取时常用,有时也会有重要信息,但一般情况下不会太关注。如果是对这部分不太了解的话,也不用担心,多看一看就自然明白了,笔者在尝试却解读之前也完全没有接触过这方面的内容。
6.CrashLog&& Memory
日志当中也提供了出错时寄存器地址里面的临近内存信息,信息量同样很丰富。之前有提到r1是与源地址有关,所以先看看r1(0xbeab238c)附近的内存情况
& &beab236c 4f659a18
df0027ad &
& &beab237c
& &beab238c 14641
& &beab239c 4c11cb40 40e1d040
40a2f614 4bdd2c94 &
& &beab23ac 14608
& &beab23bc 40a5f019 4bdd2c94
beab238c在第四行,但是注意在第三行末尾有一串类似ASCII的字符,,这即是dead,而从这里开始,一段内存为
&14641即"64,65,61,64, 00,41,41,41,
41"647141。其实不难发现这就是dead'\0'AAAA,其后位于栈上的值没有初始化,会比较随机。
所以func_b中p的起始地址应该是从
的位置开始的,至于为什么r1是beab238c,解读一下汇编代码即可很容易发现。
在Android中使用的binoc实现中,查找源文件为memcpy.s(可通过addr2line
找到文件路径和行数)。看到出错点在memcpy.s +248。
这部分源码如下:
这两段的大致意思为从r1地址读取4个字节放到d0~d3,r1地址增加,然后将d0~d3中的数据存入到r0的地址去,同时r0也增加。
现在可以回过去查看d0~d3寄存器的最后一个字节,分别是64,65,61,64。为“dead“。因此当前的r1是增加后后的地址。而此时企图对r0处无效的地址0xddeeaadd写入数据,所以出错。并显示错误地址为0xddeeaadd.
objdump,到这里,再提一提objdump的部分。
可以对共享库(.so)使用或者对目标文件(.o)使用,如果共享库比较大,那还是对被编译文件的目标文件使用比较好。通常来说Android的编译会默认保存目标文件,存放在out/target/product/xxxx/obj目录下面,于是现在找到libhello-jni.o通过objdump来查看它的信息。
Java_com_example_hellojni_HelloJni_stringFromJNI(
JNIEnv* env,
&jobject thiz )
&r4, [r4, #0]
&r1, [r4, #0]
&r1, [sp, #12]
& &char buf[10];
& &func_a(buf);
&f7ff fffe &
&&/span&Java_com_example_hellojni_HelloJni_stringFromJNI&
& &return (*env)-&NewStringUTF(env, "Hello from JNI
&r0, [r5, #0]
&r1, [pc, #28] &
&; (38 &&/span&Java_com_example_hellojni_HelloJni_stringFromJNI+0x38&)
&f8d0 229c &
&r2, [r0, #668] &
不要太在意诸如'Java_com_example_hellojni_HelloJni_stringFromJNI','{','}'之类的符号,它只是提供给我们大致的位置信息,并不是完全等同于C语言中的代码段。
之前有通过backtrace
#1看到(Java_com_example_hellojni_HelloJni_stringFromJNI+18)这样的信息,将+18转换成16进制为0x12.那么对应dump
出来的文件位置就是上面的12.指令为bl 0.这是一个常见的跳转指令。从源代码里面也可以看到开始调用func_a().
再看看func_b的代码:
func_b(char *p)
&f7ff fffe &
&&/span&strlen&
&r0, [pc, #8] &
&; (18 &&/span&func_b+0x18&)
&e8bd 4010 &
& ldmia.w &
&sp!, {r4, lr}
&f7ff bffe &
&&/span&memcpy&
&ddeeaadd &
&0xddeeaadd
先将r0(p指针的值)放入r4,调用strlen,返回值默认放入r0(值为4),再将r4取出放入r1,然后从pc+8的位置拿地址放入r0(可以看到func_b+0x18为0xddeeaadd),再跳转到memcpy。所以r0为ddeeaadd,r1为p指针的值,r4为长度。由此进行了memcpy的调用,然后出错。
通过objdump通常可以更进一步的确定错误产生的情况,对追踪代码逻辑有极大的帮助,所以在很多情况下解决问题可以只通过阅读代码,并不需要不停地加debug打印并尝试去复制它。
7.CrashLog&& Stack
当backtrace信息量极少时(没有给全函数调用栈),这是重点。
Stack一栏提供的是线程调用栈的信息。可以从右边的一些symbol大致猜测出错的位置。但由于stack上的内容可能残留未初始化或者未清空的信息,又或者存储有其他的数据,所以有时会造成一定的困惑。因此stack上的symbol虽然大部分是本次调用栈的symbol,但不一定全都是。
& beab2340 &4012ac68
& beab2344 &
& beab2348 &4f659a50
& beab234c &0000002f
& beab2350 &
& beab2354 &
& beab2358 &beab2390
& beab235c &4012ac68
& beab2360 &
& beab2364 &400cb528
&/system/lib/libc.so
& beab2368 &
& beab236c &4f659a18
& beab2370 &
&/data/app-lib/com.example.hellojni-1/libhello-jni.so
& beab2374 &
&/data/app-lib/com.example.hellojni-1/libhello-jni.so
(func_a+56)
& beab2378 &df0027ad
& beab237c &
&beab2380 &ddeeaadd
& beab2384 &
&/data/app-lib/com.example.hellojni-1/libhello-jni.so
(Java_com_example_hellojni_HelloJni_stringFromJNI+22)
栈是由下往上(frame#02-&#01-&#00)。
现在可以大致看到从#01到#00,从Java_com_example_hellojni_HelloJni_stringFromJNI进入func_a。但是这里是不能够通过左边的地址直接addr2line得到目标symbol。它是属于在内存当中的相对地址。接下来就会提到如何去通过相对地址计算可用的addr2line地址。
8.Library Base Address (共享库在内存中基地址)
通过地址计算得出可用的addr2line地址。
addr2line需要一份未去symbol的共享库。当代码没有改变时,每次生成的.so的符号位置应该是相同的。所以如果想要得到有效的符号,必须要使用程序运行时对应的未去符号的.so。
jni在运行时可以看到在java中有load_library的动作,这个动作大致可以看做将一个库文件加载到内存当中。因此这个库在内存当中就存在一个加载的基地址,但是根据内存的情况和相应的算法,基地址每次都可能会不一样。addr2line需要的地址是相对于共享库的一个绝对地址。因此现在只要能够得到共享库在内存中的基地址就能够有办法通过stack上的地址计算出可用的addr2line地址。
在上面的stack和backtrace信息当中有(Java_com_example_hellojni_HelloJni_stringFromJNI+22)和(Java_com_example_hellojni_HelloJni_stringFromJNI+18)这两个symbol的相对地址和绝对地址。
所以基地址的计算应该为对应的地址相减:0x - 0x000004cf - 0x4 =
为了验证基地址有效性,可以尝试计算0x(func_a+56)的符号:0x
-&0x = 0x4a5。
然后使用addr2line查询0x4a5得到hello-jni.c:34。
除此之外还有另一种方法计算可用的地址,同样需要stack里提供的个别的symbol信息: 例0x(func_a+56),然后之前有提到objdump可以直接将.so作为输入,这时会出来整个lib的汇编信息。然后可以从中找到"0xxxxxxxx&<func_a>:"这样的信息,前面的0xxxxxx就代表函数的在lib中的地址,在这里是"0x46c&<func_a>:"
,然后加上0x38(56)
就等于0x4a4,这个和之前有一定的差别,原因是stack上保存的会是函数返回地址,但指向的指令是相同的。
提出基地址的问题是为了进一步说明stack中的地址和backtrace中地址的不同,以及共享库被加载到内存当中指令的存在形式,但是通过比较也可以发现,在所加载的库非常大的时候(例如100M+)前一种方式得到可以用的地址会相对于后一种方式简单许多。
大多数情况下应该是不需要使用计算基地址的方式。但是也有个别的日志信息给出的backtrace不完整,导致难以解析出具体的问题所在。这个时候就需要使用基地址计算的方式得出可用的addr2line地址。
到最后看来,一般只要有一份类似于错误日志的信息文件,通常可以解决绝大部分的问题。那么如果是运行时,可以通过gdb(如果打开corefile的选项更好),或者kill
-9(同样需要打开编译选项才行)。还有就是Android系统通常内自带有debuggerd命令可以使用。详情可以从上网查阅。
最后附上本次测试的源码:/s/yVmhF5M5tTuIi
我的更多文章:
( 17:44:37)( 17:33:56)( 18:49:29)( 18:55:50)( 12:40:39)
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 yasm not found 的文章

 

随机推荐