首页 > 解决方案 > Android跟踪文件描述符在生产中泄漏

问题描述

有时我们的用户由于数据库突然无法访问而导致应用程序崩溃:

1) android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file (code 14) 

或者

2) java.lang.RuntimeException: Could not read input channel file descriptors from parcel.

或者

3) android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. # Open Cursors=1 (# cursors opened by this proc=1)

我注意到在那一刻我什至无法提取 logcat:

07-17 16:57:20.722 E/APP ( 2301): 2019-07-17_16:57:20.598+0300 [FileUtils] logcat extraction error
07-17 16:57:20.722 E/APP ( 2301): java.io.IOException: Error running exec(). Command: [logcat, -d, -v, time] Working Directory: null Environment: null
07-17 16:57:20.722 E/APP ( 2301):   at java.lang.ProcessManager.exec(ProcessManager.java:211)
07-17 16:57:20.722 E/APP ( 2301):   at java.lang.Runtime.exec(Runtime.java:174)
07-17 16:57:20.722 E/APP ( 2301):   at java.lang.Runtime.exec(Runtime.java:247)
07-17 16:57:20.722 E/APP ( 2301):   at java.lang.Runtime.exec(Runtime.java:190)
....
07-17 16:57:20.722 E/APP ( 2301): Caused by: java.io.IOException: Too many open files
07-17 16:57:20.722 E/APP ( 2301):   at java.lang.ProcessManager.exec(Native Method)
07-17 16:57:20.722 E/APP ( 2301):   at java.lang.ProcessManager.exec(ProcessManager.java:209)
07-17 16:57:20.722 E/APP ( 2301):   ... 8 more

所以我有一个问题 - 是否有可能在运行时(在用户设备上)获得我的进程中所有打开的文件描述符的列表(例如,并将其拉到 logcat)?

PS 我未能运行将 logcat 写入文件的进程。但是让转储 app.hprof 文件正常工作......虽然我在这里没有发现任何特别之处。

标签: androidsqlitedebuggingandroid-ndkadb

解决方案


不是对所提出的确切问题的答案,而是可能能够帮助您解决问题的答案:确保您的所有文件描述符都包装在 RAII 类型中,这样您就不会忘记关闭它们。在 Android 中,我们unique_fd为此使用:https ://android.googlesource.com/platform/system/core/+/master/base/include/android-base/unique_fd.h 。

这当然只有助于解决一部分泄漏。如果问题实际上是您一次使用了太多文件描述符,这将无济于事,但它会帮助您解决更常见的情况,即忘记关闭文件描述符。


推荐阅读