43

每隔一段时间,我的应用程序就会崩溃,我的日志会显示:

@@@ ABORTING: INVALID HEAP ADDRESS IN dlfree
Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1)

有时code=2,但总是Fatal signal 11invalid heap address

我已经尝试研究这意味着什么以及如何解决它。这个线程是最有帮助的;但是,我仍然没有解决方案。

当我运行几个AsyncTasks下载几个图像时会发生错误。

这是我的主要AsyncTask

public class FetchArtistImages extends AsyncTask<Void, Integer, String[]> implements Constants {

private final WeakReference<Context> contextReference;

public FetchArtistImages(Context context) {
    contextReference = new WeakReference<Context>(context);
}

@Override
protected String[] doInBackground(Void... params) {
    String[] projection = new String[] {
            Audio.Artists._ID, Audio.Artists.ARTIST
    };
    String sortOrder = Audio.Artists.DEFAULT_SORT_ORDER;
    Uri uri = Audio.Artists.EXTERNAL_CONTENT_URI;
    Cursor c = contextReference.get().getContentResolver()
            .query(uri, projection, null, null, sortOrder);
    ArrayList<String> artistIds = new ArrayList<String>();
    if (c != null) {
        int count = c.getCount();
        if (count > 0) {
            final int ARTIST_IDX = c.getColumnIndex(Audio.Artists.ARTIST);
            for (int i = 0; i < count; i++) {
                c.moveToPosition(i);
                artistIds.add(c.getString(ARTIST_IDX));
            }
        }
        c.close();
        c = null;
    }
    return artistIds.toArray(new String[artistIds.size()]);
}

@Override
protected void onPostExecute(String[] result) {
    for (int i = 0; i < result.length; i++) {
            new LastfmGetArtistImages(contextReference.get()).executeOnExecutor(
                    AsyncTask.THREAD_POOL_EXECUTOR, result[i]);
    }
    super.onPostExecute(result);
}

尽管我已经尝试过研究这是怎么回事,但在修复它时我仍然发现自己迷失了方向。如果有人有一些见解,我肯定会很高兴看到它。每次我都不会抛出错误executeAsyncTasks但我找不到太多的模式来帮助找出发生这种情况的原因。SO about 上还有其他几个线程fatal signal 11,但在我的情况下它们并没有提供太多帮助。

4

2 回答 2

44

我刚刚遇到了同样的问题,并让它处于可重现的状态。这是我得到的错误:

08-04 17:37:05.491:A/libc(4233):@@@ 中止:dlfree 中的无效堆地址 08-04 17:37:05.491:A/libc(4233):致命信号 11 (SIGSEGV) 在 0xdeadbaad (代码=1)

它归结为同时从两个不同的线程进行的函数调用。

更具体地说,这个函数是 BluetoothSocket 的 close() 方法。

我在这个网站上检查了源代码,调用不同步(不确定这是否改变了,因为它来自 Android 2.1)。

无论如何,您是否有类似的场景,即从多个线程进行函数调用?从您显示的源代码中无法确定。

你也试过不使用 THREAD_POOL_EXECUTOR 吗?根据android 开发指南

首次引入时,AsyncTask 在单个后台线程上串行执行。从 DONUT 开始,这被更改为允许多个任务并行运行的线程池。从 HONEYCOMB 开始,任务在单个线程上执行,以避免并行执行导致的常见应用程序错误。

于 2012-08-04T23:10:02.433 回答
8

我昨天有同样的错误。它总是发生,但并不总是始终如一。到目前为止,还没有提到对我来说是什么原因造成的。

我想我可能有类似的问题,因为我也在处理线程,但是我删除了所有线程并且问题仍然存在。最后,在一堆打印语句之后,我能够将其追踪到我实例化的一个类,该类有一个指针作为私有成员,但我忘了初始化指针。

后来当那个类被破坏时,它试图删除指针,但是由于指针没有初始化为NULL,它可能有也可能没有垃圾值,所以有时它不会导致崩溃,有时它会。这可能是因为当垃圾值是不属于我的内存位置时,或者当它属于我删除重要的东西时,它会导致崩溃/错误。

这是我遇到的问题的精简示例:

class BadFoo
{
public:
    BadFoo() {} // BAD! We didn't initialize the pointer
    ~BadFoo() {
        if (myPtr) {
            delete myPtr;
        }
    }
    // OTHER MEMBER FUNCTIONS HERE

private:
    int* myPtr;
}

class GoodFoo
{
public:
    GoodFoo() : myPtr(NULL) {} // GOOD! Can't be garbage value now
    ~GoodFoo() {
        if (myPtr) {
            delete myPtr;
        }
    }
    // OTHER MEMBER FUNCTIONS HERE

private:
    int* myPtr;
}

有趣的是,这个崩溃并没有发生在我的 Transformer Prime 上,而是发生在我的 Nexus4 上。只是表明我们应该在多个设备上进行测试!到目前为止,Nexus 在帮助我追踪错误方面获胜,因为它似乎更加挑剔。

于 2013-06-13T17:52:17.760 回答