Pro Micro - Upload works first time, then fails until re-flash bootloader

In a fairly complex project (Pro Micro 5V 16MHz), my sketch has started failing upload on 2nd and subsequent upload attempts, with the verbose upload log shown below.

  1. Once I get the error below, on subsequent power-up, the serial port either shows up for a few seconds, or never shows up again under either Linux or Windows 10.

  2. I then must reflash the bootloader with "Arduino as ISP", after which /dev/ttyACM0 (Linux) or com9 (Windows 10) shows up again, always on.

  3. At this point, uploading the sketch works just fine, and the project runs fine for as long as I care to check (1.5 days is longest I left Serial Monitor running). The code prints a log message to Serial Monitor every few seconds with a timer4-based 64-bit tick-counter. The tick counter is incrementing as expected.

  4. When I attempt another upload via USB, the upload seems to start, but then gives the errors shown below.

  5. Repeat from step 1.

This is 100% repeatable.

I thought maybe stack issues, but the code is running fine, and static analysis shows no problems.

RAM use is about 700 bytes out of the 2560 available.

I have several interrupts running, including ADC conversion-complete, timer4 COMPA (500KHz), and external interrupts (about 1KHz from rotary quadrature encoders when motors are moving).

I am perplexed. Wondering if perhaps I am getting interrupts during the download which trash it, but other than that uncertainty reigns.

I saw a few old posts that indicated old versions of AVRDUDE and bootloaders could have issues with certain size ranges for code, but those are all several years old and nothing similar seems to be active recently.

I tried filling up unused FLASH by creating a const char[] in flash, increasing flash use from about 14k to about 28k, but the problem persists.

Any ideas out there?

Arduino: 1.8.12 (Linux), Board: "SparkFun Pro Micro, ATmega32U4 (5V, 16 MHz)"

Sketch uses 28580 bytes (99%) of program storage space. Maximum is 28672 bytes.
Global variables use 624 bytes (24%) of dynamic memory, leaving 1936 bytes for local variables. Maximum is 2560 bytes.
Forcing reset using 1200bps open/close on port /dev/ttyACM0
PORTS {/dev/ttyACM0, } / {} => {}
PORTS {} / {} => {}
PORTS {} / {/dev/ttyACM0, } => {/dev/ttyACM0, }
Found upload port: /dev/ttyACM0
/home/.../.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude -C/home/.../.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf -v -patmega32u4 -cavr109 -P/dev/ttyACM0 -b57600 -D -Uflash:w:/tmp/arduino_build_677938/valveCntl_2_0_0.ino.hex:i 

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/home/.../.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf"
         User configuration file is "/home/.../.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/ttyACM0
         Using Programmer              : avr109
         Overriding Baud Rate          : 57600
         AVR Part                      : ATmega32U4
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PA0
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  9000  9000 0x00 0x00
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0x00 0x00
           lfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           lock           0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : butterfly
         Description     : Atmel AppNote AVR109 Boot Loader

Connecting to programmer: .
Found programmer: Id = "CATERIN"; type = S
    Software Version = 
.?; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.

Programmer supports the following devices:
    Device code: 0x44

avrdude: devcode selected: 0x44
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9587 (probably m32u4)
avrdude: reading input file "/tmp/arduino_build_677938/valveCntl_2_0_0.ino.hex"
avrdude: writing flash (28580 bytes):

Writing | ###avrdude: error: programmer did not respond to command: set addr
##avrdude: error: programmer did not respond to command: set addr
avrdude: error: programmer did not respond to command: write block
 ***failed;  

.
.
.

 ***failed;  
avrdude: Error: butterfly programmer uses avr_write_page() but does not
provide a cmd() method.
 *** page 127 (addresses 0x0200 - 0x027f) failed to write

.
.
.


 ***failed;  
avrdude: Error: butterfly programmer uses avr_write_page() but does not
provide a cmd() method.
 *** page 35 (addresses 0x6f24 - 0x6fa3) failed to write

# | 100% 0.72s

avrdude: 28580 bytes of flash written
avrdude: verifying flash memory against /tmp/arduino_build_677938/valveCntl_2_0_0.ino.hex:
avrdude: load data flash data from input file /tmp/arduino_build_677938/valveCntl_2_0_0.ino.hex:
avrdude: input file /tmp/arduino_build_677938/valveCntl_2_0_0.ino.hex contains 28580 bytes
avrdude: reading on-chip flash data:

Reading | avrdude: butterfly_recv(): programmer is not responding
#avrdude: butterfly_recv(): programmer is not responding
#avrdude: butterfly_recv(): programmer is not responding
avrdude: butterfly_recv(): programmer is not responding
##########################################the selected serial port ###### does not exist or your board is not connected
###### | 100% 23.86s

avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0020
         0xff != 0x0c
avrdude: verification error; content mismatch

avrdude done.  Thank you.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Maybe your code is to big. Try simple sketch.