Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NegativeArraySizeException crash in SecureDfuImpl.java #229

Closed
snhemanthm opened this issue Apr 16, 2020 · 6 comments
Closed

NegativeArraySizeException crash in SecureDfuImpl.java #229

snhemanthm opened this issue Apr 16, 2020 · 6 comments

Comments

@snhemanthm
Copy link

Information

DFU Bootloader version (please complete the following information):

  • SDK version: SDK 15.3
  • Bonding used: no
  • Library version: 1.10.1

Device information (please complete the following information):

  • Device: Xiaomi Mi A3
  • OS: Android 9

Describe the bug

Ran into a negative array size exception crash while performing a series of DFU operations, one after the other. This doesn't happen all the time, but we run into it a few times while upgrading hundreds of devices

Some background:

I am using the DFU library in an application that upgrades a series of nRF52832 based devices. The app picks one badge at a time, moves it into DFU mode and then starts a DFU operation. The mechanism for moving the badge to DFU mode is proprietary and doesn't use the standard buttonless service. The app does not establish its own GATT connection before handing off to the DFU operation.

Logs

Fatal Exception: java.lang.NegativeArraySizeException: -16117760
       at no.nordicsemi.android.dfu.SecureDfuImpl.sendFirmware(SecureDfuImpl.java:640)
       at no.nordicsemi.android.dfu.SecureDfuImpl.performDfu(SecureDfuImpl.java:275)
       at no.nordicsemi.android.dfu.DfuBaseService.onHandleIntent(DfuBaseService.java:1371)
       at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:76)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loop(Looper.java:193)
       at android.os.HandlerThread.run(HandlerThread.java:65)
@snhemanthm snhemanthm added the bug label Apr 16, 2020
@philips77
Copy link
Member

I'll look into this issue.

@philips77
Copy link
Member

Here's what happens:

// It may happen, that not all bytes that were sent were received by the remote device
final int bytesLost = mProgressInfo.getBytesSent() - checksum.offset;
if (bytesLost > 0) {
logw(bytesLost + " bytes were lost!");
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_WARNING,
bytesLost + " bytes were lost");
try {
// We have to reset the stream and read 'offset' number of bytes to recalculate the CRC
mFirmwareStream.reset(); // Resets to the beginning of current object
mFirmwareStream.read(new byte[info.maxSize - bytesLost]); // Reads additional bytes that were sent and received in this object
mProgressInfo.setBytesSent(checksum.offset);
} catch (final IOException e) {
loge("Error while reading firmware stream", e);
mService.terminateConnection(gatt, DfuBaseService.ERROR_FILE_IO_EXCEPTION);
return;
}

The lib crashes in line 640, reporting byte array size -16117760. This is equal to info.maxSize - bytesLost, where info.maxSize is 4096 bytes. That means, that the lib calculated bytesLost as 4096 + 16117760 = 16121856 which is wrong, as this is around 16 MB.

Do you have any logs from before the error happens? How did it go that far?

@philips77
Copy link
Member

For now I'll reopen the PR above, which does not fix this issue, but at least reports this error other way than by crashing the app.

@philips77
Copy link
Member

Thanks to #247 I have fixed the crash, but the root cause is still unknown. I'll release it in 1.10.4 now.

@philips77
Copy link
Member

I'm closing the issue. If you find the same issue in 1.10.4 or newer, please reopen.

dev-cqkct added a commit to dev-cqkct/Android-DFU-Library that referenced this issue Nov 11, 2021
  这个错误主要是在恢复DFU时,传输Object数据的时候,一次传输超过了 ObjectSize 大小,导致info.maxSize - bytesLost 变成了负数。
  现在算是彻底解决了问题: NordicSemiconductor#229
@tustar
Copy link

tustar commented May 29, 2023

@philips77 Use the DFU library 2.3.0 in an application. When the firmware is updating, the user insert wired headset。Which cause dfu failed.

// Device Firmware Upgrade
implementation 'no.nordicsemi.android:dfu:2.3.0'

05-25 14:38:37.796 3864 3864 D FirmwareUpgrader::dfuLogListener$lambda-0[85] [5][DFU] Notification received from 8ec90001-f315-4f60-9fb8-838830daea50, value (0x): 60-03-01-8D-00-00-00-4D-75-7B-C9
05-25 14:38:37.796 3864 3864 D FirmwareUpgrader::dfuLogListener$lambda-0[85] [10][DFU] Checksum received (Offset = 141, CRC = C97B754D)
05-25 14:38:37.796 3864 3864 D FirmwareUpgrader::dfuLogListener$lambda-0[85] [15][DFU] 15075 bytes were lost
05-25 14:38:37.796 3864 11960 E DfuImpl : Progress lost. Bytes sent: 15216
05-25 14:38:37.796 3864 11960 E DfuImpl : java.lang.NegativeArraySizeException: -10979
05-25 14:38:37.796 3864 11960 E DfuImpl : at no.nordicsemi.android.dfu.SecureDfuImpl.sendFirmware(SecureDfuImpl.java:643)
05-25 14:38:37.796 3864 11960 E DfuImpl : at no.nordicsemi.android.dfu.SecureDfuImpl.performDfu(SecureDfuImpl.java:262)
05-25 14:38:37.796 3864 11960 E DfuImpl : at no.nordicsemi.android.dfu.DfuBaseService.onHandleIntent(DfuBaseService.java:1394)
05-25 14:38:37.796 3864 11960 E DfuImpl : at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:78)
05-25 14:38:37.796 3864 11960 E DfuImpl : at android.os.Handler.dispatchMessage(Handler.java:106)
05-25 14:38:37.796 3864 11960 E DfuImpl : at android.os.Looper.loopOnce(Looper.java:201)
05-25 14:38:37.796 3864 11960 E DfuImpl : at android.os.Looper.loop(Looper.java:288)
05-25 14:38:37.796 3864 11960 E DfuImpl : at android.os.HandlerThread.run(HandlerThread.java:67)
05-25 14:38:37.796 3864 11960 D BluetoothGatt: cancelOpen() - device: 70:61:EE:41:C8:1E

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants