从非主线程读取/proc/self/exe时,Android权限被拒绝



我正在尝试获取/proc/self/exe的规范路径。当我在主线程上这样做时,它是有效的,当我在另一个线程上这样操作时,它会崩溃,并出现IOException:"Permission denied":

                   DBG  E  Thread: main
                        E  Path: /system/bin/app_process32
                        E  Thread: Thread-21656
            System.err  W  java.io.IOException: Permission denied
                        W      at java.io.File.canonicalizePath(Native Method)
                        W      at java.io.File.getCanonicalPath(File.java:414)
                        W      at java.io.File.getCanonicalFile(File.java:428)
                        W      at com.quanturium.testbugprocselfexe.MyActivity.getPathOfExecutable(MyActivity.java:36)
                        W      at com.quanturium.testbugprocselfexe.MyActivity.access$000(MyActivity.java:12)
                        W      at com.quanturium.testbugprocselfexe.MyActivity$1.run(MyActivity.java:26)
                        W      at java.lang.Thread.run(Thread.java:818)

代码:

@Override
protected void onCreate (Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    getPathOfExecutable(); // Works as expected
    new Thread(new Runnable() {
        @Override
        public void run ()
        {
            getPathOfExecutable(); // Trigger the IOException: Permission denied
        }
    }).start();
}
private void getPathOfExecutable()
{
    try
    {
        Log.e("DBG", "Thread: " + Thread.currentThread().getName());
        Log.e("DBG", "Path: " + new File("/proc/self/exe").getCanonicalFile().getPath());
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}

只有在build.gradle文件中将debugable配置为false时才会发生此错误

试用代码:https://github.com/quanturium/TestBugProcSelfExe

这是错误还是预期行为?获取当前可执行文件的路径的变通方法是什么?

代码是否阻塞?如果没有,那么在主线程中运行它应该不会产生任何后果。然而,您可以从另一个线程执行此操作,使用:

Context.runOnUiThread(new Runnable() {
    getPathOfExecutable();
});

这是我能想到的最干净的方法,除了编辑文件的权限(如果不在主线程上运行代码,你就无法获得文件的路径)之外,因为你在/proc/self/exe上有r/w权限。

这很奇怪,我仍在研究android上不同线程的权限差异。

如果你能让它在主线程中工作,我的意见是只在主线程上进行,而不太担心优化,因为不同线程的性能没有什么不同。

获取当前可执行文件的路径的变通方法是什么?

由于每个安卓应用程序都是从Zygote派生而来的,这是/system/bin/app_process在系统启动时创建虚拟机时的第一个Java vm进程。

如果您尝试从Android应用程序中读取/proc/self/exe,实际可执行文件将是/system/bin/app_process。即使你在应用程序的主线程之外阅读,结果也是一样的,理论上也不会出现权限错误。

你问的问题是一个奇怪的问题,我在Android 2.3.3上测试了以下代码,效果很好。

new Thread() {
    /* (non-Javadoc)
     * @see java.lang.Thread#run()
     */
    @Override
    public void run() {
        // TODO Auto-generated method stub
        super.run();
        try {
            Log.d(TAG, new File("/proc/self/exe").getCanonicalFile().getPath());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}.start();

最新更新