非常感谢两篇博客的介绍.
http://blog.csdn.net/brucexu1978/article/details/7198323
http://blog.sina.com.cn/s/blog_602f87700102uxos.html
1.首先准备的要debug的代码.首先移植下native的C程序建立Android.mk文件
2.按照bruce博客中提到的将Android.mk中增加红色字体定义:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := sendarr.c
LOCAL_MODULE := sendarr
LOCAL_CFLAGS := -Wall -Wno-unused-parameter -Werror
TARGET_BUILD_TYPE=debug
TARGET_STRIP_MODULE=false
LOCAL_SHARED_LIBRARIES := libc libcutils
include $(BUILD_EXECUTABLE)
3.source 编译环境,mm被编译模块,生成可执行程序sendarr(改编自sendevent),push到/system/bin下面
附上sendarr内容以便后续使用.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/ioctl.h>
//#include <linux/input.h> // this does not compile
#include <errno.h>
// from <linux/input.h>
struct input_event {
struct timeval time;
__u16 type;
__u16 code;
__s32 value;
};
#define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */
#define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */
#define EVIOCGKEYCODE _IOR('E', 0x04, int[2]) /* get keycode */
#define EVIOCSKEYCODE _IOW('E', 0x04, int[2]) /* set keycode */
#define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */
#define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */
#define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len) /* get unique identifier */
#define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len) /* get global keystate */
#define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len) /* get all LEDs */
#define EVIOCGSND(len) _IOC(_IOC_READ, 'E', 0x1a, len) /* get all sounds status */
#define EVIOCGSW(len) _IOC(_IOC_READ, 'E', 0x1b, len) /* get all switch states */
#define EVIOCGBIT(ev,len) _IOC(_IOC_READ, 'E', 0x20 + ev, len) /* get event bits */
#define EVIOCGABS(abs) _IOR('E', 0x40 + abs, struct input_absinfo) /* get abs value/limits */
#define EVIOCSABS(abs) _IOW('E', 0xc0 + abs, struct input_absinfo) /* set abs value/limits */
#define EVIOCSFF _IOC(_IOC_WRITE, 'E', 0x80, sizeof(struct ff_effect)) /* send a force effect to a force feedback device */
#define EVIOCRMFF _IOW('E', 0x81, int) /* Erase a force effect */
#define EVIOCGEFFECTS _IOR('E', 0x84, int) /* Report number of effects playable at the same time */
#define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */
// end <linux/input.h>
int main(int argc, char *argv[])
{
int fd,i;
FILE* filefd;
ssize_t ret;
int version;
struct input_event event;
char *line =NULL,*token,*saveptr,*str;
size_t len;
if(argc != 3) {
fprintf(stderr, "use: %s device type code value\n", argv[0]);
return 1;
}
fd = open(argv[1], O_RDWR);
if(fd < 0) {
fprintf(stderr, "could not open %s, %s\n", argv[optind], strerror(errno));
return 1;
}
filefd=fopen(argv[2],"r");
if(filefd==NULL) {
fprintf(stderr, "could not open %s, %s\n", argv[optind], strerror(errno));
return 1;
}
if (ioctl(fd, EVIOCGVERSION, &version)) {
fprintf(stderr, "could not get driver version for %s, %s\n", argv[optind], strerror(errno));
return 1;
}
while( getline(&line,&len,filefd) != -1){
memset(&event, 0, sizeof(event));
for(i=1,str=line; ;i++, str=NULL){
token = strtok_r(str," ",&saveptr);
if(token==NULL)
break;
if(i==1)
event.type = strtol(token,NULL,16);
if(i==2)
event.code = strtol(token,NULL,16);
if(i==3)
event.value = strtol(token,NULL,16);
}
ret = write(fd, &event, sizeof(event));
if(ret < (ssize_t) sizeof(event)) {
fprintf(stderr, "write event failed, %s\n", strerror(errno));
return -1;
}
}
close(fd);
fclose(filefd);
return 0;
}
/*sendarr /dev/input/event* file.txt*
4.gdbserver使用代码树中prebuilts/misc/android-arm/gdbserver/gdbserver文件,push到device端,启动device端gdbserver.
gdbserver 192.168.133.70:2000 /system/bin/sendarr /dev/input/event /sdcard/arr.txt
Process /system/bin/sendarr created; pid = 8103
Listening on port 2000
5.PC端启动调试
prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-gdb out/target/product/msm8909/obj/EXECUTABLES/sendarr_intermediates/sendarr
GNU gdb (GDB) 7.6
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-linux-gnu --target=arm-linux-android".
For bug reporting instructions, please see:
<http://source.android.com/source/report-bugs.html>...
Reading symbols from /mnt/zhaojd/8909la/sendarr...(no debugging symbols found)...done.
(gdb) target remote 192.168.133.70:2000
Remote debugging using 192.168.133.70:2000
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
0xb6f24a94 in ?? ()
(gdb) list //列举代码, + , -
Cannot access memory at address 0x0
40 #define EVIOCGEFFECTS _IOR('E', 0x84, int) /* Report number of effects playable at the same time */
41
42 #define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */
43
44 // end <linux/input.h>
45
48 int main(int argc, char *argv[])
49 {
(gdb) (gdb) b 58 //设置断点
Breakpoint 1 at 0xb6f875a2: file system/core/sendarr/sendarr.c, line 58.
(gdb) c //开始执行
Continuing.
warning: Could not load shared library symbols for 13 libraries, e.g. /system/bin/linker.
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"?
Breakpoint 1, main (argc=3, argv=0xbede18e4) at system/core/sendarr/sendarr.c:58
58 if(argc != 3) {
(gdb) s //单步执行
49 {
(gdb)