Android笔记 跟踪c++代码报错

 问题

用logcat抓取到报错如下

10-26 15:14:46.777  3174  3174 I crash_dump32: obtaining output fd from tombstoned, type: kDebuggerdTombstone
10-26 15:14:46.778  1810  1810 I /system/bin/tombstoned: received crash request for pid 3152
10-26 15:14:46.779  3174  3174 I crash_dump32: performing dump of process 3152 (target tid = 3152)
10-26 15:14:46.779  3174  3174 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
10-26 15:14:46.780  3174  3174 F DEBUG   : Build fingerprint: 'Allwinner/virgo_perf1/virgo-perf1:8.1.0/OPM1.171019.026/20191026-150808:userdebug/test-keys'
10-26 15:14:46.780  3174  3174 F DEBUG   : Revision: '0'
10-26 15:14:46.780  3174  3174 F DEBUG   : ABI: 'arm'
10-26 15:14:46.780  3174  3174 F DEBUG   : pid: 3152, tid: 3152, name: r.handwritedemo  >>> com.softwinner.handwritedemo <<<
10-26 15:14:46.780  3174  3174 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x906e7573
10-26 15:14:46.780  3174  3174 F DEBUG   :     r0 906e7573  r1 906e7573  r2 00000010  r3 00000005
10-26 15:14:46.780  3174  3174 F DEBUG   :     r4 906e7573  r5 00000073  r6 be86e8bc  r7 ffffffff
10-26 15:14:46.780  3174  3174 F DEBUG   :     r8 00000000  r9 ffffffff  sl 00000014  fp ad133dce
10-26 15:14:46.780  3174  3174 F DEBUG   :     ip 80000000  sp be86e818  lr adc4c00f  pc adc27fc2  cpsr 80070030
10-26 15:14:46.688  3152  3152 I r.handwritedemo: type=1400 audit(0.0:47): avc: denied { open } for path="/dev/input" dev="tmpfs" ino=8987 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:input_device:s0 tclass=dir permissive=1
10-26 15:14:46.688  3152  3152 I r.handwritedemo: type=1400 audit(0.0:48): avc: denied { read write } for name="event4" dev="tmpfs" ino=1762 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:input_device:s0 tclass=chr_file permissive=1
10-26 15:14:46.688  3152  3152 I r.handwritedemo: type=1400 audit(0.0:49): avc: denied { open } for path="/dev/input/event4" dev="tmpfs" ino=1762 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:input_device:s0 tclass=chr_file permissive=1
10-26 15:14:46.688  3152  3152 I r.handwritedemo: type=1400 audit(0.0:50): avc: denied { ioctl } for path="/dev/input/event4" dev="tmpfs" ino=1762 ioctlcmd=0x4506 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:input_device:s0 tclass=chr_file permissive=1
10-26 15:14:47.214  3174  3174 F DEBUG   : 
10-26 15:14:47.214  3174  3174 F DEBUG   : backtrace:
10-26 15:14:47.214  3174  3174 F DEBUG   :     #00 pc 00019fc2  /system/lib/libc.so (strlen+21)
10-26 15:14:47.214  3174  3174 F DEBUG   :     #01 pc 0003e00b  /system/lib/libc.so (__vfprintf+3754)
10-26 15:14:47.214  3174  3174 F DEBUG   :     #02 pc 00052755  /system/lib/libc.so (vsnprintf+128)
10-26 15:14:47.214  3174  3174 F DEBUG   :     #03 pc 00006483  /system/lib/liblog.so (__android_log_print+54)
10-26 15:14:47.215  3174  3174 F DEBUG   :     #04 pc 00004cad  /system/lib/libhandwritten.so (input_reader_init(void*)+224)
10-26 15:14:47.215  3174  3174 F DEBUG   :     #05 pc 000046c9  /system/lib/libhandwritten.so (android::HandWriteHandler::start()+228)
10-26 15:14:47.215  3174  3174 F DEBUG   :     #06 pc 000a118b  /system/lib/libandroid_runtime.so (android::nativeHandwrittenStart(_JNIEnv*, _jobject*, long long, _jobject*, _jobject*, _jobject*, _jobject*, int, int, int, int)+622)
10-26 15:14:47.215  3174  3174 F DEBUG   :     #07 pc 007dde4d  /system/framework/arm/boot-framework.oat (offset 0x2f2000) (android.view.Surface.nativeHandwrittenStart+220)
10-26 15:14:47.215  3174  3174 F DEBUG   :     #08 pc 00408375  /system/lib/libart.so (art_quick_invoke_stub_internal+68)
10-26 15:14:47.215  3174  3174 F DEBUG   :     #09 pc 0040d4e7  /system/lib/libart.so (art_quick_invoke_stub+230)
10-26 15:14:47.215  3174  3174 F DEBUG   :     #10 pc 000b00b7  /system/lib/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+138)

不像JAVA层的代码那样,告诉你哪一行报了什么错,如何去查呢?

解决步骤
1.从logcat中可以到初步报错信息

10-26 15:14:47.215  3174  3174 F DEBUG   :     #04 pc 00004cad  /system/lib/libhandwritten.so (input_reader_init(void*)+224)

这行报错信息,正是我改动的代码所编译出来的库,报错信息还说了是哪个函数(input_reader_init),但是224不是行数

2.找到libhandwritten.so

路径:out/target/product/virgo-perf1/symbols/system/lib/libhandwritten.so

3.把libhandwritten.so拷贝到prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin下面去,这个路径含有一个名字含有addr2line的工具

4.执行./arm-eabi-addr2line -Cfe libhandwritten.so 0x00004cad,注意最后一个参数对应log中的,然后得到结果

epoll_register_all_input(int, char const*)
frameworks/base/libs/handwritten/InputReader.cpp:117

报错在frameworks/base/libs/handwritten/InputReader.cpp的117行

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个问题比较广泛,需要分步骤讲解。以下是一些可能的步骤和代码示例: 1. 创建一个笔记类(Note): ```java public class Note { private int id; private String title; private String content; private Date createdDate; private Date modifiedDate; public Note() { // 构造函数 } // getter 和 setter 方法 // 重写 toString 方法,方便调试 @Override public String toString() { return "Note{" + "id=" + id + ", title='" + title + '\'' + ", content='" + content + '\'' + ", createdDate=" + createdDate + ", modifiedDate=" + modifiedDate + '}'; } } ``` 2. 创建一个数据库帮助类(DbHelper): ```java public class DbHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "notes.db"; private static final int DATABASE_VERSION = 1; private static final String TABLE_NAME = "notes"; private static final String COLUMN_ID = "_id"; private static final String COLUMN_TITLE = "title"; private static final String COLUMN_CONTENT = "content"; private static final String COLUMN_CREATED_DATE = "created_date"; private static final String COLUMN_MODIFIED_DATE = "modified_date"; // SQL 语句 private static final String SQL_CREATE_ENTRIES = "CREATE TABLE " + TABLE_NAME + " (" + COLUMN_ID + " INTEGER PRIMARY KEY," + COLUMN_TITLE + " TEXT," + COLUMN_CONTENT + " TEXT," + COLUMN_CREATED_DATE + " INTEGER," + COLUMN_MODIFIED_DATE + " INTEGER)"; public DbHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(SQL_CREATE_ENTRIES); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 数据库升级 } } ``` 3. 创建一个数据访问层(NoteDao): ```java public class NoteDao { private SQLiteDatabase db; private DbHelper dbHelper; public NoteDao(Context context) { dbHelper = new DbHelper(context); db = dbHelper.getWritableDatabase(); } public long add(Note note) { ContentValues values = new ContentValues(); values.put(DbHelper.COLUMN_TITLE, note.getTitle()); values.put(DbHelper.COLUMN_CONTENT, note.getContent()); values.put(DbHelper.COLUMN_CREATED_DATE, note.getCreatedDate().getTime()); values.put(DbHelper.COLUMN_MODIFIED_DATE, note.getModifiedDate().getTime()); return db.insert(DbHelper.TABLE_NAME, null, values); } public int update(Note note) { ContentValues values = new ContentValues(); values.put(DbHelper.COLUMN_TITLE, note.getTitle()); values.put(DbHelper.COLUMN_CONTENT, note.getContent()); values.put(DbHelper.COLUMN_MODIFIED_DATE, note.getModifiedDate().getTime()); String whereClause = DbHelper.COLUMN_ID + "=?"; String[] whereArgs = { String.valueOf(note.getId()) }; return db.update(DbHelper.TABLE_NAME, values, whereClause, whereArgs); } public int delete(Note note) { String whereClause = DbHelper.COLUMN_ID + "=?"; String[] whereArgs = { String.valueOf(note.getId()) }; return db.delete(DbHelper.TABLE_NAME, whereClause, whereArgs); } public List<Note> getAll() { List<Note> notes = new ArrayList<>(); Cursor cursor = db.query(DbHelper.TABLE_NAME, null, null, null, null, null, DbHelper.COLUMN_MODIFIED_DATE + " DESC"); while (cursor.moveToNext()) { Note note = new Note(); note.setId(cursor.getInt(cursor.getColumnIndex(DbHelper.COLUMN_ID))); note.setTitle(cursor.getString(cursor.getColumnIndex(DbHelper.COLUMN_TITLE))); note.setContent(cursor.getString(cursor.getColumnIndex(DbHelper.COLUMN_CONTENT))); note.setCreatedDate(new Date(cursor.getLong(cursor.getColumnIndex(DbHelper.COLUMN_CREATED_DATE)))); note.setModifiedDate(new Date(cursor.getLong(cursor.getColumnIndex(DbHelper.COLUMN_MODIFIED_DATE)))); notes.add(note); } cursor.close(); return notes; } } ``` 4. 创建一个笔记列表界面(NoteListActivity): ```java public class NoteListActivity extends AppCompatActivity { private static final int REQUEST_CODE_ADD = 1; private static final int REQUEST_CODE_EDIT = 2; private ListView listView; private List<Note> notes; private NoteDao noteDao; private ArrayAdapter<Note> adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_note_list); noteDao = new NoteDao(this); listView = findViewById(R.id.list_view); notes = noteDao.getAll(); adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, notes); listView.setAdapter(adapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Note note = notes.get(position); Intent intent = new Intent(NoteListActivity.this, NoteEditActivity.class); intent.putExtra("note", note); startActivityForResult(intent, REQUEST_CODE_EDIT); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { switch (requestCode) { case REQUEST_CODE_ADD: Note note = (Note) data.getSerializableExtra("note"); long id = noteDao.add(note); note.setId((int) id); notes.add(0, note); adapter.notifyDataSetChanged(); break; case REQUEST_CODE_EDIT: note = (Note) data.getSerializableExtra("note"); noteDao.update(note); adapter.notifyDataSetChanged(); break; } } } public void onAddButtonClick(View view) { Intent intent = new Intent(this, NoteEditActivity.class); startActivityForResult(intent, REQUEST_CODE_ADD); } } ``` 5. 创建一个笔记编辑界面(NoteEditActivity): ```java public class NoteEditActivity extends AppCompatActivity { private EditText titleEditText; private EditText contentEditText; private Note note; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_note_edit); titleEditText = findViewById(R.id.title_edit_text); contentEditText = findViewById(R.id.content_edit_text); note = (Note) getIntent().getSerializableExtra("note"); if (note == null) { note = new Note(); } else { titleEditText.setText(note.getTitle()); contentEditText.setText(note.getContent()); } } public void onSaveButtonClick(View view) { note.setTitle(titleEditText.getText().toString()); note.setContent(contentEditText.getText().toString()); note.setModifiedDate(new Date()); Intent intent = new Intent(); intent.putExtra("note", note); setResult(RESULT_OK, intent); finish(); } } ``` 这些代码只是一个简单的示例,实际开发中需要根据具体需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值