18 Apr 2013
由于最近需要调试C++程序,以后都是暴力调试的,暴力调试就是在源码中把想要得到的内容通过log的形式输出,这就调试速度快精准度高,但是得到的内容有限,所以才开始使用GDB来高度C++。
现在如果想要通过Google搜索关于Debug Android Ndk的内容很多都是旧版本的,如今ADT插件的发展已经支持NDK的调试的,不需要安装Sequoyah插件与一大堆配置,只需要简单几步即可调试应用,下面记录下调试的步骤,方便以后查阅。
- 系统: OS X 10.8.3
- Eclipse: Juno 4.2.1
- ADT: r21.1.0
- NDK: android-ndk-r8e
一、创建工程
二、添加Native支持
三、切换至C/C++视图,方便C/C++代码编写
四、检查工程目录结构是否正常,如果没有includes文件夹可以关闭工程再重新打开
五、这样一个完整的工程就创建完成了,接下来我们要实现的功能是点击一下按键,显示从Jni返回的字符串。
六、修改activity_main.xml布局文件
七、修改MainActivity.java
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void call_jni(View v) {
((TextView) findViewById(R.id.textView1)).setText(jni_call());
}
private native String jni_call();
static {
System.loadLibrary("DebugNdkTest");
}
}
八、获取jni_call的jni头文件
$ cd $DebugNdkTest/jni
$ javah -classpath ../bin/classes com.linguofeng.debugndktest.MainActivity
九、修改DebugNdkTest.cpp
#include "com_linguofeng_debugndktest_MainActivity.h"
JNIEXPORT jstring JNICALL Java_com_linguofeng_debugndktest_MainActivity_jni_1call
(JNIEnv * env, jobject) {
return env->NewStringUTF("Hello From JNI");
}
十、运行点击按键将会看到
接下来就是debug了,debug前需要修改工程属性
在DebugNdkTest.cpp文件第6行打个断点
现在就可以debug了
当点击访问JNI按钮的时候就会停在断点处了,现在就可以像java的debug一样调试了,很方便。
18 Apr 2013
OS X自带的gdb版本有点低了,就使用brew安装了一个最新版本,可是遇到了
please check gdb is codesigned - see taskgated(8)
首先创建一个证书,用于给gdb签名用的,没图片的选项保持默认即可
用刚刚创建的证书给gdb签名
$ codesign -s gdb-cert /usr/local/bin/gdb
输入密码即可
参考: http://sourceware.org/gdb/wiki/BuildingOnDarwin
18 Apr 2013
1. 安装
$ brew install SpiderMonkey
2. Hello World
#include "jsapi.h"
static JSClass global_class = {
"global", JSCLASS_GLOBAL_FLAGS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
JSCLASS_NO_OPTIONAL_MEMBERS
};
void reportError(JSContext *cx, const char *message, JSErrorReport *report)
{
fprintf(stderr, "%s:%u:%s\n",
report->filename ? report->filename : "<no filename=\"filename\">",
(unsigned int) report->lineno,
message);
}
int main(int argc, const char *argv[])
{
JSRuntime *rt;
JSContext *cx;
JSObject *global;
// 创建新的运行时
rt = JS_NewRuntime(8 * 1024 * 1024);
if (rt == NULL)
return 1;
// 创建新的上下文并与运行时绑定
cx = JS_NewContext(rt, 8192);
if (cx == NULL)
return 1;
JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT);
JS_SetVersion(cx, JSVERSION_LATEST);
JS_SetErrorReporter(cx, reportError);
global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
if (global == NULL)
return 1;
// 实例化内置全局对象
if (!JS_InitStandardClasses(cx, global))
return 1;
const char *script = "'Hello ' + 'World!'";
jsval rval;
JSString *str;
JSBool ok;
const char *filename = "noname";
uintN lineno = 0;
ok = JS_EvaluateScript(cx, global, script, strlen(script),
filename, lineno, &rval);
if (!rval | rval == JS_FALSE)
return 1;
str = JS_ValueToString(cx, rval);
printf("%s\n", JS_EncodeString(cx, str));
JS_DestroyContext(cx);
JS_DestroyRuntime(rt);
JS_ShutDown();
return 0;
}
3. 编译与执行
$ g++ -o bin/HelloJS -I/usr/local/include/js -lmozjs185 src/HelloJS.cpp
$ ./bin/HelloJS
4. 看来以后有时间还是要学习javascript
17 Apr 2013
$ cd $NDK_ROOT/sample/hello-jni
$ ndk-build NDK_DEBUG=1
$ android update project -p . -t android-17
$ ant debug install
$ ndk-gdb --start
这时会启动应用,接着就可以使用gdb的命令了
(gdb) list
(gdb) break 30
(gdb) info breakpoints
(gdb) continue
Continuing. // 然后手动重启应用就会停在30行断点处了
17 Apr 2013
由于目前Cocos2d-x中的libtiff.a静态库中存在main主函数,导致gdb调试时会出现问题,现在需要重新编译一个没有main函数的libtiff静态库
$ git clone git://github.com/dumganhar/libtiff.git
$ cp -r libtiff $NDK_ROOT/samples/hello-jni/jni/tiff
$ cd libtiff
$ ./configure
# 目的是生成tif_config.h和tiffconf.h两个文件
$ cp libtiff/{tif_config.h,tiffconf.h} $NDK_ROOT/samples/hello-jni/jni/tiff/libtiff
$ vim $NDK_ROOT/samples/hello-jni/jni/tiff/libtiff/tif_config.h
# 注释120行的#define HAVE_SEARCH_H 1与206行的#define LZMA_SUPPORT 1
$ vim $NDK_ROOT/samples/hello-jni/jni/tiff/libtiff/mkg3states.c
# 注释掉main函数
$ vim $NDK_ROOT/samples/hello-jni/jni/Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := tiff
LOCAL_TIFF_SRC_FILES := \
tiff/libtiff/tif_dirread.c \
tiff/libtiff/tif_zip.c \
tiff/libtiff/tif_flush.c \
tiff/libtiff/tif_next.c \
tiff/libtiff/tif_ojpeg.c \
tiff/libtiff/tif_dirwrite.c \
tiff/libtiff/tif_dirinfo.c \
tiff/libtiff/tif_dir.c \
tiff/libtiff/tif_compress.c \
tiff/libtiff/tif_close.c \
tiff/libtiff/tif_tile.c \
tiff/libtiff/tif_open.c \
tiff/libtiff/tif_getimage.c \
tiff/libtiff/tif_pixarlog.c \
tiff/libtiff/tif_warning.c \
tiff/libtiff/tif_dumpmode.c \
tiff/libtiff/tif_jpeg.c \
tiff/libtiff/tif_jbig.c \
tiff/libtiff/tif_predict.c \
tiff/libtiff/mkg3states.c \
tiff/libtiff/tif_write.c \
tiff/libtiff/tif_error.c \
tiff/libtiff/tif_version.c \
tiff/libtiff/tif_print.c \
tiff/libtiff/tif_color.c \
tiff/libtiff/tif_read.c \
tiff/libtiff/tif_extension.c \
tiff/libtiff/tif_thunder.c \
tiff/libtiff/tif_lzw.c \
tiff/libtiff/tif_fax3.c \
tiff/libtiff/tif_luv.c \
tiff/libtiff/tif_codec.c \
tiff/libtiff/tif_unix.c \
tiff/libtiff/tif_packbits.c \
tiff/libtiff/tif_aux.c \
tiff/libtiff/tif_fax3sm.c \
tiff/libtiff/tif_swab.c \
tiff/libtiff/tif_strip.c
LOCAL_TIFF_SRC_FILES += tiff/port/lfind.c
LOCAL_SRC_FILES := $(LOCAL_TIFF_SRC_FILES)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/tiff/libtiff
LOCAL_WHOLE_STATIC_LIBRARIES := cocos_jpeg_static
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
LOCAL_STATIC_LIBRARIES := tiff
include $(BUILD_SHARED_LIBRARY)
$(call import-module,libjpeg)
参考: https://code.google.com/p/tiffonandroid/source/browse/tiffviewer/project/jni/Android.mk
$ ndk-build NDK_MODULE_PATH=$COCOS2DX_ROOT/cocos2dx/platform/third_party/android/prebuilt
$ cp obj/local/armeabi/libtiff.a $COCOS2DX_ROOT/cocos2dx/platform/third_party/android/prebuilt/libtiff/libs/armeabi
首先编译时要加NDK_DEBUG=1
$ cd $COCOS2DX_ROOT/samples/Cpp/HelloCpp/proj.android
$ ./build_native.sh NDK_DEBUG=1
AndroidManifest.xml增加android:debuggable="true"
...
安装应用到模拟器
$ android update project -p . -t android-17
$ ant debug install
开始进行调试
$ ./ndkgdb.sh
(gdb) b HelloWorldScene.cpp:83
(gdb) c # 这时点击退出按键将会断点到83行
Breakpoint 1, HelloWorld::menuCloseCallback (this=0x2a19b3a0, pSender=0x2a14b8d0) at jni/../../Classes/HelloWorldScene.cpp:83
83 CCDirector::sharedDirector()->end();
(gdb) q