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

Fix terminal write edge cases; add one read mode and add quell command #1025

Merged
merged 39 commits into from Jul 18, 2022

Conversation

stefanrueger
Copy link
Collaborator

@stefanrueger stefanrueger commented Jul 12, 2022

For details, see #1020 (comment)

Using strtoll() can only return numbers in the range [-2^63, 2^63-1]. This
means that 0xffffFFFFffffFFFF (2^64-1) will be out of range and is written as
max LL. Actually, every 64-bit number with high-bit set will wrongly be
written as max LL.

This commit uses strtoull() instead to fix this, and checks for unsiged out-
of-range error. strtoull() also has the neat benefit that input with a minus
sign is treated like C unsigned numbers, ie, -u is also a valid unsigned
number if only u is one. In case the input is meant to be treated as signed,
it is therefore still OK to use strtoull() in the first instance only that in
this case a second check against the range of the signed domain is necessary.
Integers can be hexadecimal, decimal or octal. An optional case-insensitive
suffix specifies their size: HH: 8 bit, H/S: 16 bit, L: 32 bit, LL: 64 bit

An optional U suffix makes a number unsigned. Ordinary 0x hex numbers are
always treated as unsigned. +0x or -0x hex numbers are treated as signed
unless they have a U suffix. Unsigned integers cannot be larger than 2^64-1.

If n is an unsigned integer then -n is also a valid unsigned integer as in C.

Signed integers must fall into the [-2^63, 2^63-1] range or a correspondingly
smaller range when a suffix specifies a smaller type. Out of range signed
numbers trigger a warning.

Ordinary 0x hex numbers with n hex digits (counting leading zeros) use
the smallest size of 1, 2, 4 and 8 bytes that can accommodate any n-digit hex
number. If a suffix specifies a size explicitly the corresponding number of
least significant bytes are written. Otherwise, signed and unsigned integers
alike occupy the smallest of 1, 2, 4, or 8 bytes needed to accommodate them
in their respective representation.
The code no longer accepts valid mantissa-only doubles that are integer
rejects, eg, 078 or ULL overflows. These are most likely input errors by
the user: 8 is not an octal digit, they might have typed 17 hex digits,
not 16. It's just too hard to explain that 0xffffFFFFffffFFFFf writes
0x4430000000000000, which is the correct double representation of the
valid 17-digit hex mantissa that strtod() is perfectly happy to accept.
Sets the quell_progress global variable that can be, and is, consulted by
programmers.

Setting quell_progress to a positive number also switches off progress
bars. It is currently not possible to switch on progress bars again: that
is enabled in main.c once at the start of AVRDUDE.

That code in main should move to avr.c to enable report_update() to consult
quell_progress directly. Will do at another time when touching main.c and
avr.c. smr
@stefanrueger
Copy link
Collaborator Author

For details, see #1020 (comment)

Tips for reviewing:

Either read term.c on its own or follow the commits one by one to see what's happened. Here is a command to check terminal write cases with the following input file test-cases.txt:

$ avrdude -qqp m328p -c usbtiny -t < test-cases.txt |&  \
  grep -v '^avrdude> write eeprom 0x180 16 0x55 ...$' | \
  grep -v '^avrdude> read  eeprom 0x180 16$' | \
  grep -v '^avrdude> $' | \
  grep  -v '>>>'

@mcuee mcuee added bug Something isn't working enhancement New feature or request labels Jul 12, 2022
@mcuee
Copy link
Collaborator

mcuee commented Jul 14, 2022

Which floating point designations and sizes to use in terminal write?

  1. C syntax: no suffix = 64-bit double, f/F suffix = 32-bit float, l/L = 80/128-bit long double
  2. avr-gcc and avr-libc: @dl8dtl, what's that? Current implementation makes double and float 32 bit alike
  3. d/D suffix = double, f/F or no suffix = float

Because we're working with 8-bit microcontrollers that by default is working with 32-bit floats, option 3 makes the most sense IMO.

And I'm not sure 128-bit floats is necessary.

I agree. I believe both avr-gcc and Microchip XC8 support only 32bit float/double/long double.

@mcuee
Copy link
Collaborator

mcuee commented Jul 14, 2022

In the chardump output, why replace . with ? when the data is 0xff? Also, the that the line starting with >>> is also gone, at least on MacOS.

Interesting. It is okay under MSYS2 mingw64 under Windows. I will test out macOS as well.

/c/work/avr/avrdude_test/avrdude_sr/build_mingw64/src
$ echo "read eeprom 0 0x20" | ./avrdude -c usbasp -qqp m328p -t
avrdude> >>> read eeprom 0 0x20
0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

avrdude>

$ ./avrdude.exe -v

avrdude.exe: Version 7.0-20220713 (901d49c)
             Copyright (c) Brian Dean, http://www.bdmicro.com/
             Copyright (c) Joerg Wunsch

             System wide configuration file is "C:/work/avr/avrdude_test/avrdude_sr/build_mingw64/src/avrdude.conf"


avrdude.exe: no programmer has been specified on the command line or the config file
             Specify a programmer using the -c option and try again

@dl8dtl
Copy link
Contributor

dl8dtl commented Jul 14, 2022

2. avr-gcc and avr-libc: @dl8dtl, what's that? Current implementation makes double and float 32 bit alike

AVR-GCC can produce 64-bit double for some time now, and avr-libc caught up implementing the multilib scheme Georg-Johann Lay suggested. There are several things (like printf implementation) though that can only handle 32-bit double by now.

@dl8dtl
Copy link
Contributor

dl8dtl commented Jul 14, 2022

I'd also vote for option 3, default to 32-bit "double" unless "d" is given.

@dl8dtl
Copy link
Contributor

dl8dtl commented Jul 14, 2022

You could also go FORTRAN :-), 128E5 is REAL * 4, 128D5 is REAL * 8.

:-))

(Just kidding, of course.)

@mcuee
Copy link
Collaborator

mcuee commented Jul 14, 2022

In the chardump output, why replace . with ? when the data is 0xff? Also, the that the line starting with >>> is also gone, at least on MacOS.

@MCUdude
Indeed there is an issue under macOS. Strange.

mcuee@mcuees-Mac-mini src % echo "read eeprom 0 0x20" | ./avrdude -c usbasp -qqp m328p -t
0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |????????????????|
0010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |????????????????|

Without this PR it is okay.

mcuee@mcuees-Mac-mini src % which avrdude
/opt/homebrew/bin/avrdude

mcuee@mcuees-Mac-mini src % echo "read eeprom 0 0x20" | avrdude -c usbasp -qqp m328p -t 
>>> read eeprom 0 0x20 
0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

@mcuee
Copy link
Collaborator

mcuee commented Jul 14, 2022

@MCUdude

I know the reason and the work-around under macOS.

Once I build with readline support under macOS, it is all fine.

Edit: sorry no, this is not working.

@mcuee
Copy link
Collaborator

mcuee commented Jul 14, 2022

@stefanrueger

It seems to me the following does not work for macOS.
f8145ae

@@ -1477,7 +1477,7 @@ int terminal_mode(PROGRAMMER * pgm, struct avrpart * p)
      return argc;
    }

#if defined(WIN32)
#if !defined(HAVE_LIBREADLINE) || defined(WIN32)
    fprintf(stdout, ">>> ");
    for (int i=0; i<argc; i++)
      fprintf(stdout, "%s ", argv[i]);

A quick hack (not the proper fix) can sorted out the echo issue, but I have no idea why ff becomes ?.


mcuee@mcuees-Mac-mini avrdude_sr % git diff
diff --git a/src/term.c b/src/term.c
index ea34d5e..71e39bb 100644
--- a/src/term.c
+++ b/src/term.c
@@ -1481,7 +1481,7 @@ int terminal_mode(PROGRAMMER * pgm, struct avrpart * p)
       return argc;
     }
 
-#if !defined(HAVE_LIBREADLINE) || defined(WIN32)
+#if !defined(HAVE_LIBREADLINE) || defined(WIN32) || defined(__APPLE__)
     fprintf(stdout, ">>> ");
     for (int i=0; i<argc; i++)
       fprintf(stdout, "%s ", argv[i]);

mcuee@mcuees-Mac-mini avrdude_sr % echo "read eeprom 0 0x20" | 
./build_darwin/src/avrdude -c usbasp -qqp m328p -t
>>> read eeprom 0 0x20 
0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |????????????????|
0010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |????????????????|

…lpha() etc

Some C libraries assign true to isalpha(0xff), isdigit(0xff) or
ispunct(0xff), which means that the Operating System terminal sees a
character 0xff which it may not have a useful display character for.

This commit only outputs printable ASCII characters for an AVRDUDE
terminal dump reducing the risk of the OS terminal not being able
to print the character properly.
@stefanrueger
Copy link
Collaborator Author

It seems to me Issue 2 is still there.

@mcuee No it isn't! The test used avrdude without the PR. I can tell, because the PR also changes the error message can't parse byte "nonsense" to can't parse data nonsense, and the test shows the misleading pre-PR message (byte).

In the chardump output, why replace . with ? when the data is 0xff?

@MCUdude chardump_line() does not do that!

Explanation. Amongst other things, the PR defuses the isctype() bomb that makes terminal crash on some systems:
isspace() and fellow is...() functions only work on integer that are either -1 (EOF) or in the uchar range 0..255. Give it any other number, and the behaviour is undefined.
term.c calls is...() with char, which on most systems is signed, and sign-extends almost half of possible inputs to illegal inputs -128, ... -2. Hence the crash.
I fixed this by casting to unsigned char or changing the data type to unsigned char.

Now, the code for which letter to print in chardump() is still the same:

    buffer[i] = '.';
    if (isalpha(b[i]) || isdigit(b[i]) || ispunct(b[i]))
      buffer[i] = b[i];
    else if (isspace(b[i]))
      buffer[i] = ' ';

No ? assignment in sight, right? I suspect what happens is that the C library of that compiler has assigned true to isalpha(0xff), isdigit(0xff) or ispunct(0xff), and your OS-terminal decided to show a ? for a letter it didn't have a font character for. Test my hpothesis by piping the AVRDUDE-terminal output to sed "s/?/+/g"; if you see plusses it is wrong.

Solution. Upgrade to Linux (just kidding) or replace above with

    buffer[i] = isascii(b[i]) && isspace(b[i])? ' ':
      isascii(b[i]) && isgraph(b[i])? b[i]: '.';

That should work. isascii() protects users from Libraries that return unexpected vaues for is...() calls with 0x80...0xff.

Will do in a push to this PR shortly.

@stefanrueger
Copy link
Collaborator Author

I'd also vote for option 3, default to 32-bit "double" unless "d" is given.

Option 3 it is. Suggest also keeping F for continuity.

@stefanrueger
Copy link
Collaborator Author

You could also go FORTRAN

Well, the distinguished FORTRAN would be most happy if they could cut and paste lists of constants from their source onto into an AVRDUDE terminal write for the ATtiny85 EEPROM that keeps the moon rocket in orbit ;-). The ATtiny85, not the EEPROM that is.

@stefanrueger
Copy link
Collaborator Author

Can we require the readline library?

The prompt ">>>" problem has to do with readline(), its poor man's fgets() replacement and OS-terminal echo. One of these could happen when I/O is a pipe/file ($ echo w ee 0 nonsense | avrdude -qqp m328p -c usbtiny -t 2>&1 | cat):

avrdude> w ee 0 nonsense
avrdude (write): can't parse data nonsense

A. Good. No redundant >>> w ee 0 nonsense line. Can grep -v "^avrdude> " if I don't want echo.

avrdude> w ee 0 nonsense
>>> w ee 0 nonsense
avrdude (write): can't parse data nonsense

B. Annoying. Looks unprofessional. Echos the input twice. Also, when written to file/pipe.

avrdude> avrdude (write): can't parse data nonsense

C. Does not echo the input, but echos the prompt?!? For a long successful input file you get a ton of prompts (w/o newline).

avrdude (write): can't parse data nonsense

D. Reasonable. Only shows output when redirected to pipe/file. Makes sense, but not great for logging etc.

Somehow we seem to be getting a mixture of A, B or C.

Two questions:

  1. What do we want?
  2. How do we get there?

The best user experience is with readline. It would be best if we were able to require that library for building avrdude. Going without is painful as it means we would have to write a poor man's replacement that is less of a mess than the current implementation.

For now, I'll adopt the quick fix that @mcuee suggested.

@stefanrueger
Copy link
Collaborator Author

Just pushed a few more changes to this PR.

  • Hardens terminal dump against compiler's C library implementation
  • Removed long double data type
  • Default floating point numbers to 32-bit, use suffix F and D
  • Quick fix for MacOS ">>>" prompt

@stefanrueger
Copy link
Collaborator Author

I now consider this PR finished, and will start work on the actual issue of making writes to flash work.

Unless I hear otherwise, I plan to merge the PR into main in the next few days.

@MCUdude
Copy link
Collaborator

MCUdude commented Jul 14, 2022

Seems to work fine on MacOS now. Excellent work @stefanrueger!

$ ./avrdude -cusbtiny -patmega2560 -t

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e9801 (probably m2560)
avrdude> read eeprom 0 0x100
>>> read eeprom 0 0x100 

Reading | ################################################## | 100% 0.42s

0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0030  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0040  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0050  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0060  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0070  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0080  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0090  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00a0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00b0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00c0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00d0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00e0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00f0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

avrdude> write eeprom 0 0xdeadbeef 'a' 'v' 'r' "Hello World\n" 0x00000002
>>> write eeprom 0 0xdeadbeef 'a' 'v' 'r' "Hello World\n" 0x00000002 

Writing | ################################################## | 100% 0.13s

avrdude> read eeprom 0 0x40
>>> read eeprom 0 0x40 

Reading | ################################################## | 100% 0.10s

0000  ef be ad de 61 76 72 48  65 6c 6c 6f 20 57 6f 72  |....avrHello Wor|
0010  6c 64 0a 00 02 00 00 00  ff ff ff ff ff ff ff ff  |ld .............|
0020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0030  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

``

@mcuee
Copy link
Collaborator

mcuee commented Jul 15, 2022

Windows: MSYS2 mingw64. I think everything is okay now.

/c/work/avr/avrdude_test/avrdude_sr/build_mingw64_nt-10.0-22000/src
$ yes w ee 0 nonsense | head -3 | ./avrdude -qqp t13a -c usbasp -t 2>&1 | cat
avrdude> >>> w ee 0 nonsense
avrdude.exe (write): can't parse data nonsense
avrdude> >>> w ee 0 nonsense
avrdude.exe (write): can't parse data nonsense
avrdude> >>> w ee 0 nonsense
avrdude.exe (write): can't parse data nonsense
avrdude>

Windows Powershell.

PS C:\work\avr\avrdude_test\avrdude-7.0_bin64> echo 'w ee 0 nonsense' |
 .\avrdude_pr1025v3.exe -qqp t13a -c usbasp -t 2>&1
avrdude> >>> w ee 0 nonsense
avrdude> avrdude_pr1025v3.exe (write): can't parse data nonsense

@mcuee
Copy link
Collaborator

mcuee commented Jul 15, 2022

Can we require the readline library?

@stefanrueger
readline is actually availabe for MSYS2 MinGW. So I also built the readline version.

/c/work/avr/avrdude_test/avrdude_sr
$ git diff
diff --git a/src/term.c b/src/term.c
index e779f84..95f9bcc 100644
--- a/src/term.c
+++ b/src/term.c
@@ -1473,7 +1473,7 @@ int terminal_mode(PROGRAMMER * pgm, struct avrpart * p)
       return argc;
     }

-#if !defined(HAVE_LIBREADLINE) || defined(WIN32) || defined(__APPLE__)
+#if !defined(HAVE_LIBREADLINE)
     fprintf(stdout, ">>> ");
     for (int i=0; i<argc; i++)
       fprintf(stdout, "%s ", argv[i]);

The output under MSYS2 mingw64 is now in line the D output, without echo.

$ yes w ee 0 nonsense | head -3 | ./avrdude -qqp t13a -c usbasp -t 2>&1
avrdude> avrdude.exe (write): can't parse data nonsense
avrdude> avrdude.exe (write): can't parse data nonsense
avrdude> avrdude.exe (write): can't parse data nonsense
avrdude>

$ yes w ee 0 nonsense | head -3 | ./avrdude -qqp t13a -c usbasp -t 2>&1 | cat
avrdude> avrdude.exe (write): can't parse data nonsense
avrdude> avrdude.exe (write): can't parse data nonsense
avrdude> avrdude.exe (write): can't parse data nonsense
avrdude>

But the output under Windows Terminal Powershell is a bit strange.

PS C:\work\avr\avrdude_test\avrdude-7.0_bin64> echo 'w ee 0 nonsense' | 
.\avrdude_pr1025v3_readline.exe -qqp t13a -c usbasp -t 2>&1
avrdude> avrdude> avrdude_pr1025v3_readline.exe (write): can't parse data nonsense

Readline is also available for MSVC from vcpkg. But I have no idea how to build with MSVC.
https://vcpkg.info/port/readline

@mcuee
Copy link
Collaborator

mcuee commented Jul 15, 2022

@stefanrueger
Somehow I can not get this shell command to work under macOS, no matter it is under zsh or bash. Strange.

yes w ee 0 nonsense | head -3 | ./avrdude -qqp t13a -c usbasp -t 2>&1 | cat

Default build without libreadline. I think this is okay.

mcuee@mcuees-Mac-mini src % echo "read eeprom 0 0x20" | ./avrdude -qqp t13a -c usbasp -t
>>> read eeprom 0 0x20 
0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

Building with libreadline.


mcuee@mcuees-Mac-mini avrdude_sr % git diff
diff --git a/src/term.c b/src/term.c
index e779f84..95f9bcc 100644
--- a/src/term.c
+++ b/src/term.c
@@ -1473,7 +1473,7 @@ int terminal_mode(PROGRAMMER * pgm, struct avrpart * p)
       return argc;
     }
 
-#if !defined(HAVE_LIBREADLINE) || defined(WIN32) || defined(__APPLE__)
+#if !defined(HAVE_LIBREADLINE)
     fprintf(stdout, ">>> ");
     for (int i=0; i<argc; i++)
       fprintf(stdout, "%s ", argv[i]);

mcuee@mcuees-Mac-mini src % echo "read eeprom 0 0x20" | ./avrdude -qqp t13a -c usbasp -t
0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

mcuee@mcuees-Mac-mini src % ./avrdude -qqp t13a -c usbasp -t 
avrdude> read eeprom 0 0x40
0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0030  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

avrdude> write eeprom 0 0xdeadbeef 'a' 'v' 'r' "Hello World\n" 0x00000002
avrdude> read eeprom 0 0x40
0000  ef be ad de 61 76 72 48  65 6c 6c 6f 20 57 6f 72  |....avrHello Wor|
0010  6c 64 0a 00 02 00 00 00  ff ff ff ff ff ff ff ff  |ld .............|
0020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0030  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

@mcuee
Copy link
Collaborator

mcuee commented Jul 15, 2022

@stefanrueger
There seems to be a issue if a string starts with a space. Same for the readline version or no-readline version.

mcuee@mcuees-Mac-mini src % ./avrdude -qqp t13a -c usbasp -t
avrdude> erase
avrdude: erasing chip
avrdude> read eeprom 0 0x40
0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0030  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

avrdude> write eeprom 0 0xdeadbeef 'a' 'v' 'r' " Hello World\n" 0x00000002
avrdude (write): can't parse data Hello 

Question: is this a problem or not?

avrdude> write eeprom 0 0xdeadbeef 'a' 'v' 'r' "" "Hello World\n" 0x00000002
avrdude> read eeprom 0 0x40
0000  ef be ad de 61 76 72 00  48 65 6c 6c 6f 20 57 6f  |....avr.Hello Wo|
0010  72 6c 64 0a 00 02 00 00  00 ff ff ff ff ff ff ff  |rld ............|
0020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0030  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

avrdude> write eeprom 0  "Hello World from ATtiny13A!" "" ' ' "" "\n"
avrdude> read eeprom 0 0x40
0000  48 65 6c 6c 6f 20 57 6f  72 6c 64 20 66 72 6f 6d  |Hello World from|
0010  20 41 54 74 69 6e 79 31  33 41 21 00 00 00 00 00  | ATtiny13A!.....|
0020  0a 00 ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  | ...............|
0030  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

@mcuee
Copy link
Collaborator

mcuee commented Jul 15, 2022

Under Linux (Ubuntu 20.04).

mcuee@UbuntuSwift3:~/build/avr/avrdude_sr/build_linux/src$ yes w ee 0 nonsense | head -3 | 
./avrdude -qqp t13a -c usbasp -t 2>&1 | cat
avrdude> >>> w ee 0 nonsense 
avrdude (write): can't parse data nonsense
avrdude> >>> w ee 0 nonsense 
avrdude (write): can't parse data nonsense
avrdude> >>> w ee 0 nonsense 
avrdude (write): can't parse data nonsense
avrdude> mcuee@UbuntuSwift3:~/build/avr/avrdude_sr/build_linux/src$

mcuee@UbuntuSwift3:~/build/avr/avrdude_sr/build_linux/src$ ./avrdude -qqp t13a -c usbasp -t
avrdude> erase
>>> erase 
avrdude: erasing chip
avrdude> read eeprom 0 0x40
>>> read eeprom 0 0x40 
0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0030  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

avrdude> write eeprom 0 0xdeadbeef 'a' 'v' 'r' " Hello World\n" 0x00000002
>>> write eeprom 0 0xdeadbeef 'a' 'v' 'r' " Hello World\n" 0x00000002 
Segmentation fault (core dumped)

mcuee@UbuntuSwift3:~/build/avr/avrdude_sr/build_linux/src$ gdb --args ./avrdude -qqp t13a -c usbasp -t
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./avrdude...
(gdb) run
Starting program: /home/mcuee/build/avr/avrdude_sr/build_linux/src/avrdude -qqp t13a -c usbasp -t
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff7b98700 (LWP 6816)]
avrdude> erase
>>> erase 
avrdude: erasing chip
avrdude> read eeprom 0 0x40
>>> read eeprom 0 0x40 
0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0030  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

avrdude> write eeprom 0 0xdeadbeef 'a' 'v' 'r' " Hello World\n" 0x00000002
>>> write eeprom 0 0xdeadbeef 'a' 'v' 'r' " Hello World\n" 0x00000002 

Thread 1 "avrdude" received signal SIGSEGV, Segmentation fault.
__strncpy_avx2 () at ../sysdeps/x86_64/multiarch/strcpy-avx2.S:858
858	../sysdeps/x86_64/multiarch/strcpy-avx2.S: No such file or directory.
(gdb) bt
#0  __strncpy_avx2 () at ../sysdeps/x86_64/multiarch/strcpy-avx2.S:858
#1  0x000055555555e171 in strncpy (__len=18446744073709551615, __src=0x5555555e18c7 "", __dest=0x555555b106e0 "")
    at /usr/include/x86_64-linux-gnu/bits/string_fortified.h:106
#2  cmd_write (pgm=0x55555564f2b0, p=0x555555712df0, argc=<optimized out>, argv=0x5555555e1840)
    at /home/mcuee/build/avr/avrdude_sr/src/term.c:799
#3  0x000055555555f594 in do_cmd (argv=0x5555555e1840, argc=11, p=0x555555712df0, pgm=0x55555564f2b0)
    at /home/mcuee/build/avr/avrdude_sr/src/term.c:1416
#4  terminal_mode (pgm=0x55555564f2b0, p=0x555555712df0) at /home/mcuee/build/avr/avrdude_sr/src/term.c:1484
#5  0x000055555555bb33 in main (argc=<optimized out>, argv=<optimized out>)
    at /home/mcuee/build/avr/avrdude_sr/src/main.c:1225
(gdb) quit
A debugging session is active.

	Inferior 1 [process 6812] will be killed.

Quit anyway? (y or n) y

bt with debug build.

mcuee@UbuntuSwift3:~/build/avr/avrdude_sr/build_debug/src$ gdb --args ./avrdude -qqp t13a -c usbasp -t
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./avrdude...
(gdb) run
Starting program: /home/mcuee/build/avr/avrdude_sr/build_debug/src/avrdude -qqp t13a -c usbasp -t
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff7b98700 (LWP 7479)]
avrdude> write eeprom 0 0xdeadbeef 'a' 'v' 'r' " Hello World\n" 0x00000002
>>> write eeprom 0 0xdeadbeef 'a' 'v' 'r' " Hello World\n" 0x00000002 

Thread 1 "avrdude" received signal SIGSEGV, Segmentation fault.
__strncpy_avx2 () at ../sysdeps/x86_64/multiarch/strcpy-avx2.S:859
859	../sysdeps/x86_64/multiarch/strcpy-avx2.S: No such file or directory.
(gdb) bt
#0  __strncpy_avx2 () at ../sysdeps/x86_64/multiarch/strcpy-avx2.S:859
#1  0x000055555555f542 in cmd_write (pgm=0x555555668190, p=0x55555572c090, argc=11, argv=0x5555555fa9f0)
    at /home/mcuee/build/avr/avrdude_sr/src/term.c:799
#2  0x0000555555561198 in do_cmd (pgm=0x555555668190, p=0x55555572c090, argc=11, argv=0x5555555fa9f0)
    at /home/mcuee/build/avr/avrdude_sr/src/term.c:1403
#3  0x0000555555561474 in terminal_mode (pgm=0x555555668190, p=0x55555572c090)
    at /home/mcuee/build/avr/avrdude_sr/src/term.c:1484
#4  0x000055555555d3a1 in main (argc=6, argv=0x7fffffffdf28) at /home/mcuee/build/avr/avrdude_sr/src/main.c:1225
(gdb) quit
A debugging session is active.

	Inferior 1 [process 7475] will be killed.

Quit anyway? (y or n) y

@mcuee
Copy link
Collaborator

mcuee commented Jul 15, 2022

Under FreeBSD it seems to crash more often than Linux.

mcuee@freebsdx64vm:~/build/avrdude_sr/build_freebsd/src $ sudo ./avrdude -c usbasp -qqp t13a -t
avrdude> erase
avrdude: erasing chip
avrdude> read eeprom 0 0x40
0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0030  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

avrdude> write eeprom 0 0xdeadbeef 'a' 'v' 'r' "Hello World\n" 0x00000002
avrdude> read eeprom 0 0x40
0000  ef be ad de 61 76 72 48  65 6c 6c 6f 20 57 6f 72  |....avrHello Wor|
0010  6c 64 0a 00 02 00 00 00  ff ff ff ff ff ff ff ff  |ld .............|
0020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0030  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

mcuee@freebsdx64vm:~/build/avrdude_sr/build_freebsd/src $ sudo ./avrdude -c usbasp -qpp t13a -t
avrdude> erase
avrdude: erasing chip
avrdude> read eeprom 0 0x40
0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0030  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

avrdude> write eeprom 0 0xdeadbeef 'a' 'v' 'r' " Hello World\n" 0x00000002
Segmentation fault

mcuee@freebsdx64vm:~/build/avrdude_sr/build_freebsd/src $ sudo ./avrdude -c usbasp -qqp t13a -t
avrdude> write eeprom 0 0xdeadbeef 'a' 'v' 'r' "" "Hello World\n" 0x00000002
avrdude> read eeprom 0 0x40
0000  ef be ad de 61 76 72 00  48 65 6c 6c 6f 20 57 6f  |....avr.Hello Wo|
0010  72 6c 64 0a 00 02 00 00  00 ff ff ff ff ff ff ff  |rld ............|
0020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0030  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

avrdude> write eeprom 0  "Hello World from ATtiny13A!" "" ' ' "" "\n"
Segmentation fault

@stefanrueger
Copy link
Collaborator Author

There seems to be a issue if a string starts with a space.

Wow! Great catch, @mcuee. I haven't touched the parsing of the input lines and their splitting into tokens, so this is probably a "pre-existing" condition that escaped me when I read the code. What about the change that I just pushed?

@mcuee
Copy link
Collaborator

mcuee commented Jul 16, 2022

There seems to be a issue if a string starts with a space.

Wow! Great catch, @mcuee. I haven't touched the parsing of the input lines and their splitting into tokens, so this is probably a "pre-existing" condition that escaped me when I read the code. What about the change that I just pushed?

@stefanrueger
Yes the latest change fixed the issue. Great. Tested under both Linux and Windows. Later also macOS.

BTW, I just found out that previously I did not build the Linux version with readline support as I did not install the development package under my Ubuntu 20.04 machine (dual boot with Windows 11). Now I built it with proper readline support.

/c/work/avr/avrdude_test/avrdude_sr/build_mingw64_nt-10.0-22000/src
$ ./avrdude.exe -qqp m328p -c usbasp -t
avrdude> erase
>>> erase
avrdude.exe: erasing chip
avrdude> write eeprom 0 0xdeadbeef 'a' 'v' 'r' " Hello World\n" 0x00000002
>>> write eeprom 0 0xdeadbeef 'a' 'v' 'r' " Hello World\n" 0x00000002
avrdude> read eeprom 0 0x20
>>> read eeprom 0 0x20
0000  ef be ad de 61 76 72 20  48 65 6c 6c 6f 20 57 6f  |....avr Hello Wo|
0010  72 6c 64 0a 00 02 00 00  00 ff ff ff ff ff ff ff  |rld ............|

mcuee@UbuntuSwift3:~/build/avr/avrdude_sr$ ./build_linux/src/avrdude -qqp m328p -c usbasp -t
avrdude> erase
avrdude: erasing chip
avrdude> write eeprom 0 0xdeadbeef 'a' 'v' 'r' " Hello World\n" 0x00000002
avrdude> read eeprom 0 0x20
0000  ef be ad de 61 76 72 20  48 65 6c 6c 6f 20 57 6f  |....avr Hello Wo|
0010  72 6c 64 0a 00 02 00 00  00 ff ff ff ff ff ff ff  |rld ............|

avrdude> quit

mcuee@mcuees-Mac-mini avrdude_sr % ./build_darwin/src/avrdude -qqp m328p -c usbasp -t
avrdude> erase
>>> erase 
avrdude: erasing chip
avrdude> write eeprom 0 0xdeadbeef 'a' 'v' 'r' " Hello World\n" 0x00000002
>>> write eeprom 0 0xdeadbeef 'a' 'v' 'r' " Hello World\n" 0x00000002 
avrdude> read eeprom 0 0x20
>>> read eeprom 0 0x20 
0000  ef be ad de 61 76 72 20  48 65 6c 6c 6f 20 57 6f  |....avr Hello Wo|
0010  72 6c 64 0a 00 02 00 00  00 ff ff ff ff ff ff ff  |rld ............|

avrdude> quit
>>> quit 

And yes, latest git main or 7.0 release will crash. So this is not introduced by your PR but rather pre-exisitng bug.
Example for the 7.0 release.


PS C:\work\avr\avrdude_test\avrdude-7.0_bin64\old_bin> .\avrdude.exe -c usbasp -qqp m328p -t
avrdude> write eeprom 0 0xdeadbeef 'a' 'v' 'r' "Hello World\n" 0x00000002
>>> write eeprom 0 0xdeadbeef 'a' 'v' 'r' "Hello World\n" 0x00000002
avrdude> read eeprom 0 0x20
>>> read eeprom 0 0x20
0000  ef be ad de 61 76 72 48  65 6c 6c 6f 20 57 6f 72  |....avrHello Wor|
0010  6c 64 5c 6e 00 02 00 00  00 ff ff ff ff ff ff ff  |ld\n............|

avrdude> write eeprom 0 0xdeadbeef 'a' 'v' 'r' " Hello World\n" 0x00000002
>>> write eeprom 0 0xdeadbeef 'a' 'v' 'r' " Hello World\n" 0x00000002 (crashed)
PS C:\work\avr\avrdude_test\avrdude-7.0_bin64\old_bin>

@mcuee
Copy link
Collaborator

mcuee commented Jul 17, 2022

I think this is good enough now to be merged.

@stefanrueger stefanrueger merged commit 494199f into avrdudes:main Jul 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants