androidandroid-native-library

Check failed: receiver != nullptr virtual (SIGABRT) when writing to local storage


I have a method

   fun generateIdentity(deviceId:String, environment: String) {

     val identity= Identity()

     identity.deviceId = deviceId
     identity.environment = environment

    AppLog.i(TAG, "generateIdentity()")

    if (!configDirectory.exists()) {
        configDirectory.mkdirs()
    }

    val identityFile = File("$configDirectory/identity.json")

    if (identityFile.exists()) {
        identityFile.delete()
    }

    identityFile.createNewFile()

    val jsonIdentity = GsonBuilder().setPrettyPrinting().create().toJson(identity)

    try {
        val buf = BufferedWriter(FileWriter(identityFile, true))
        buf.append(jsonIdentity)
        buf.newLine()
        buf.close()
    } catch (e: IOException) {
        AppLog.e(TAG, e.printStackTrace().toString())
    }
}

that writes a serialized object

 class Identity{

@Expose
@SerializedName("device-id")
var deviceId: String = ""

@Expose
@SerializedName("environment")
var environment: String =""
}

to local storage as a JSON file.

When .toJson() is called on the identity object in the Gson building process, a crash occurs in the native layer that provides a very long list of logs beginning with

03-09 14:20:08.416 7468-7468/ A/art: art/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc:801] Check failed: receiver != nullptr virtual 

and ending with

03-09 14:20:08.799 7468-7468/? A/libc: Fatal signal 6 (SIGABRT), code -6 in tid 7468 ()

No tombstone is generated. This is a seemingly trivial bit of code that has worked in the past, not sure what change has caused this to start happening. How do I investigate what is causing this?


Solution

  • I put the whole serialization and file writing process into a coroutine like this:

    val jsonCoversionResult: Deferred<String> = GlobalScope.async {
             GsonBuilder()
                 .setPrettyPrinting()
                 .create()
                 .toJson(
                     identity)
         }
    
         runBlocking {
             val jsonIdentity = jsonCoversionResult.await()
    
             try {
                 val buf = BufferedWriter(FileWriter(identityFile, true))
                 buf.append(jsonIdentity)
                 buf.newLine()
                 buf.close()
             } catch (e: IOException) {
                 AppLog.e(TAG, e.printStackTrace().toString())
             }
         }
    

    I'm writing for an AOSP version with proprietary hardware, and memory management gets funky sometimes for reasons I don't understand, but this did work.