in Ubuntu 18.04 or later, or similar Debian derivatives, it looks like
udev rules no longer stop ModemManager from interfering with the serial device enough to confuse
avrdude, so uploading from the Arduino environment usually fails.
The only option is to stop ModemManager:
sudo systemctl stop ModemManager.serviceIf you do not use modems, you can safely disable the entire service,
sudo systemctl disable ModemManager.servicejust remember to enable it first if you ever need to use a modem.
I do believe the root cause is a race window in systemd (udev, specifically), that allows ModemManager access to the device regardless of the environment variables, and just happens to be remarkably easy to hit on some computers.

This is what happens when you let crap programmers aggregate useful-looking code and push it to millions of users.

I only found out about this when a friend was having odd problems with Pro Micro clones in the Arduino environment on Ubuntu 18.04 LTS.
If the default
dialout group ownership does not work, you can create say
/lib/udev/rules.d/81-arduino.rules to change the device group to whatever suits you better. For Arduino Leonardo and Pro Micro clones,
# Arduino Leonardo, Pro Micro clones
ATTRS{idVendor}=="2341", ATTRS{idProduct}=="0036", GROUP:="dialout", MODE:="0660", ENV{ID_MM_CANDIDATE}:="", ENV{ID_MM_DEVICE_IGNORE}:="1", ENV{ID_MM_PORT_IGNORE}:="1", ENV{MTP_NO_PROBE}:="1"
ATTRS{idVendor}=="2341", ATTRS{idProduct}=="8036", GROUP:="dialout", MODE:="0660", ENV{ID_MM_CANDIDATE}:="", ENV{ID_MM_DEVICE_IGNORE}:="1", ENV{ID_MM_PORT_IGNORE}:="1", ENV{MTP_NO_PROBE}:="1"
Just remember to run
sudo udevadm control --reload to tell udev to use the new rules.
I also change my Arduino
boards.txt to have
leonardo.upload.use_1200bps_touch=false
as I prefer to have a set sequence for updating sketches: connecting RST to GND for a couple of seconds, then selecting the board in Tool > Port and hitting Sketch > Update, within eight seconds of disconnecting RST from GND. (They're next to each other on the Pro Micro clones.)
The default "set baud rate to 1200" trick to reset the microcontrollers and run the bootloader is problematic, again due to how systemd's udev handles the device attach/detach cases. It is avoidable by completely reworking the way the Arduino environment selects and accesses microcontrollers that switch USB VID:PID to a different one during firmware upload, but the way Arduino does it, used to work.. the systemd developers don't give a shit about that, though.
(Basically, the baud rate reset by the microcontroller causes udev to give the usb serial interface a new USB serial device, and since Arduino assumes it stays the same [for historical reasons!], it loses the serial connection to the boot loader on the microcontroller. Keeping the RST at GND for a second makes sure the old device is removed first, so when you disconnect RST from GND, udev
should give it the same USB serial device.)
The proper way, of course, is to label each microcontroller based on their USB device path, and retry access every 0.1s or so for a couple of seconds, as the USB device will be down during resets/switching to bootloader mode. You could easily support any number of simultaneously connected microcontrollers then too.
I'm tempted to do something about this. Why the hell do people insist on building big frameworks and overcomplicated monolithic applications? Small modular tools and the Unix philosophy has a proven track record over decades, whereas big sprawly blobs rarely survive a decade without a drastic rewrite!
