Error in avrdude: free(): invalid next size (normal): 0x000000000112c720 ??

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I just now started getting errors from avrdude after flashing a chip.

 

I had gotten an error 139 from make

Makefile:17: recipe for target 'program' failed
make: *** [program] Error 139

Now, it appeared that the programming and verification went okay, just this strange error that didn't seem to make sense. So I purged avrdude and reinstalled it. Now I get the following, which looks like a bug in avrdude maybe but again ... programming seems to have succeded.

 

*** Error in `avrdude': free(): invalid next size (normal): 0x000000000112c720 ***
Makefile:17: recipe for target 'program' failed
make: *** [program] Error 134

 

This is my Makefile that was used when the error was produced:

hexclock.hex : hexclock.elf
	avr-objcopy -j .text -j .data -j .bss -O ihex hexclock.elf hexclock.hex

hexclock.elf : hexclock.o
	avr-gcc -mmcu=attiny2313a -Wall -Werror -o hexclock.elf hexclock.o -Wl,-Map,hexclock.map

hexclock.o : hexclock.c
	avr-gcc -c -Os -mmcu=attiny2313a -std=gnu99 -fshort-enums -Wall -Werror -o hexclock.o hexclock.c
clean :
	rm -f hexclock.o hexclock.elf hexclock.map hexclock.hex hexclock.s

program :
	sudo avrdude -v -p attiny2313 -c usbtiny -P usb -U flash:w:hexclock.hex:i

asm:
	avr-gcc -S -Os -mmcu=attiny2313a -std=gnu99 -fshort-enums -Wall -Werror -o hexclock.s hexclock.c

 

I have never gotten these errors before. Here is the entire verbose output from avrdude (and make ... at the end of it all): http://pastebin.com/dN8aByEv. Thanks in advance to the ones that can help me fix this, or at least tell me what is wrong.

Last Edited: Sun. Sep 6, 2015 - 09:49 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
hexclock.hex : hexclock.elf
	avr-objcopy -j .text -j .data -j .bss -O ihex hexclock.elf hexclock.hex

What on earth are you including .bss in the load image for ?!?!

 

If you don't know how to invoke the tools get "Mfile" for AVR and use the template it provides - it knows the correct rules for building AVR software and that does no inlcude doing a -j for .bss. It also abstracts the source file names to a single "SRC=" line at the top of the Makefile so if you add uart.c to hexclock.c or want to rename hexclock.c to decclock.c or something you only edit one occurrence in the entire Makefile.

 

PS just noticed your registered ID here - kind of ironic cheeky

Last Edited: Mon. Sep 7, 2015 - 09:28 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's not the problem ... it made no difference as to the error. Used that makefile before without error, maybe .bss didn't need to be in there but I still got the same error after taking it out. It does actually program though ... even though there is that error.

 

Would you like to explain the .bss segment to me as it applies here, and when you really do need it?  My knowledge of assembler and machine architecture is admittedly not the best, but I'd like to learn as much as I can.  I do appreciate the link to the Makefile template, that is handy. Btw ... it's not exactly ironic. It would be more ironic maybe if the code wasn't bad but you thought it was.

Last Edited: Tue. Sep 8, 2015 - 09:10 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

if you want to understand BSS (Block Started by Symbol) then perhaps start by reading this page in the user manual:

 

http://www.nongnu.org/avr-libc/u...

 

That shows the layout of variables in RAM. .data are placed first and they are followed by .bss. Any local/autos you use are created on the stack and that grows down from the other end of memory. .data are variables you create that are global and have initial values like:

int n = 12345;

int main(void) {
    
}

In this code "n" is a global and it has an initial value. So it is a .data variable. On the other hand:

int m;

int main(void) {
    
}

In this "m" is a global but has no initial value (so C guarantees it will be 0). It is in the .bss section.

 

Now .data and .bss (as the picture on that page shows) are areas in RAM. However for my example n=12345 the 12345 value has to get into its RAM location as a starting value somehow. So C groups all the .data variables together and then can equally create a block of al their initial values together. Now this is an AVR where flash and RAM are quite separate. So somehow the program+data needs to go into flash but before C starts (entry to main()) the block of initial values in RAM needs to get from flash to RAM. So if I build my first example here for AVR the cod generated is:

00000000 <__vectors>:
   0:	12 c0       	rjmp	.+36     	; 0x26 <__ctors_end>
   2:	24 c0       	rjmp	.+72     	; 0x4c <__bad_interrupt>
   4:	23 c0       	rjmp	.+70     	; 0x4c <__bad_interrupt>
   6:	22 c0       	rjmp	.+68     	; 0x4c <__bad_interrupt>
   8:	21 c0       	rjmp	.+66     	; 0x4c <__bad_interrupt>
   a:	20 c0       	rjmp	.+64     	; 0x4c <__bad_interrupt>
   c:	1f c0       	rjmp	.+62     	; 0x4c <__bad_interrupt>
   e:	1e c0       	rjmp	.+60     	; 0x4c <__bad_interrupt>
  10:	1d c0       	rjmp	.+58     	; 0x4c <__bad_interrupt>
  12:	1c c0       	rjmp	.+56     	; 0x4c <__bad_interrupt>
  14:	1b c0       	rjmp	.+54     	; 0x4c <__bad_interrupt>
  16:	1a c0       	rjmp	.+52     	; 0x4c <__bad_interrupt>
  18:	19 c0       	rjmp	.+50     	; 0x4c <__bad_interrupt>
  1a:	18 c0       	rjmp	.+48     	; 0x4c <__bad_interrupt>
  1c:	17 c0       	rjmp	.+46     	; 0x4c <__bad_interrupt>
  1e:	16 c0       	rjmp	.+44     	; 0x4c <__bad_interrupt>
  20:	15 c0       	rjmp	.+42     	; 0x4c <__bad_interrupt>
  22:	14 c0       	rjmp	.+40     	; 0x4c <__bad_interrupt>
  24:	13 c0       	rjmp	.+38     	; 0x4c <__bad_interrupt>

00000026 <__ctors_end>:
  26:	11 24       	eor	r1, r1
  28:	1f be       	out	0x3f, r1	; 63
  2a:	cf e5       	ldi	r28, 0x5F	; 95
  2c:	d4 e0       	ldi	r29, 0x04	; 4
  2e:	de bf       	out	0x3e, r29	; 62
  30:	cd bf       	out	0x3d, r28	; 61

00000032 <__do_copy_data>:
  32:	10 e0       	ldi	r17, 0x00	; 0
  34:	a0 e6       	ldi	r26, 0x60	; 96
  36:	b0 e0       	ldi	r27, 0x00	; 0
  38:	e4 e5       	ldi	r30, 0x54	; 84
  3a:	f0 e0       	ldi	r31, 0x00	; 0
  3c:	02 c0       	rjmp	.+4      	; 0x42 <__SREG__+0x3>
  3e:	05 90       	lpm	r0, Z+
  40:	0d 92       	st	X+, r0
  42:	a2 36       	cpi	r26, 0x62	; 98
  44:	b1 07       	cpc	r27, r17
  46:	d9 f7       	brne	.-10     	; 0x3e <__SP_H__>
  48:	02 d0       	rcall	.+4      	; 0x4e <main>
  4a:	02 c0       	rjmp	.+4      	; 0x50 <_exit>

0000004c <__bad_interrupt>:
  4c:	d9 cf       	rjmp	.-78     	; 0x0 <__vectors>

0000004e <main>:
int n = 12345;

int main(void) {
    
}
  4e:	08 95       	ret

00000050 <_exit>:
  50:	f8 94       	cli

00000052 <__stop_program>:
  52:	ff cf       	rjmp	.-2      	; 0x52 <__stop_program>

Within that the C compiler has added some code called _do_copy_data() that I have highlighted above. That is basically a loop to copy from flash (LPM) and write to RAM (ST X+). In this case it's only copying the 2 bytes (x03039) that make up the vaolue 12345. This ensures that by the time the "RCALL main" is executed the location of "n" in RAM is holding 12345. For this to work the initial 0x3039 had to be in flash. In fact it is at location 0x0054 right after the code shown here. It got there because of the "-j .text -j.data" in the objcopy that ensures the block of initial .data values is in the .hex file (and hence the flash) right after the .text of the program.

 

.bss is different. The short program I showed for "m" above looks like this:

         [SNIP FIRST BIT]
00000026 <__ctors_end>:
  26:	11 24       	eor	r1, r1
  28:	1f be       	out	0x3f, r1	; 63
  2a:	cf e5       	ldi	r28, 0x5F	; 95
  2c:	d4 e0       	ldi	r29, 0x04	; 4
  2e:	de bf       	out	0x3e, r29	; 62
  30:	cd bf       	out	0x3d, r28	; 61

00000032 <__do_clear_bss>:
  32:	10 e0       	ldi	r17, 0x00	; 0
  34:	a0 e6       	ldi	r26, 0x60	; 96
  36:	b0 e0       	ldi	r27, 0x00	; 0
  38:	01 c0       	rjmp	.+2      	; 0x3c <.do_clear_bss_start>

0000003a <.do_clear_bss_loop>:
  3a:	1d 92       	st	X+, r1

0000003c <.do_clear_bss_start>:
  3c:	a2 36       	cpi	r26, 0x62	; 98
  3e:	b1 07       	cpc	r27, r17
  40:	e1 f7       	brne	.-8      	; 0x3a <.do_clear_bss_loop>
  42:	02 d0       	rcall	.+4      	; 0x48 <main>
  44:	02 c0       	rjmp	.+4      	; 0x4a <_exit>

00000046 <__bad_interrupt>:
  46:	dc cf       	rjmp	.-72     	; 0x0 <__vectors>

00000048 <main>:
int m;

int main(void) {
    
}
  48:	08 95       	ret

0000004a <_exit>:
  4a:	f8 94       	cli

0000004c <__stop_program>:
  4c:	ff cf       	rjmp	.-2      	; 0x4c <__stop_program>

In this case the code provided by the compiler/library is _do_clear_bss(). That's because C guarantees that variables such as "m", without and assigned initial value, are guaranteed to be 0. So this loop stores 0 (in R1) to each location in .bss (ST X+). But no block of data had to go into the flash image for this. And this is why -j .bss" does not make sense.

 

Anyway back to your issue. Your thread title says 0x112c720. Think about that number in decimal for a minute. It is 18,007,840. That's about 18 megabytes. Such an address does not make sense to either the flash or the RAM space of any AVR8. The largest possible flash (one of the Xmegas) is 384K and the largest RAM is 16K (mega1284P) so if you have created a file that contains some object at location 18,000,000 it cannot be right!

 

Have a look at the actual .hex file you are passing to avrdude that you have created. Does it really contain an 18MB address? BTW in .hex the address field is just 4 hex digits so can only be 0000 to FFFF which is 64K. So to get "beyond" 64K the hex file may contain type 04 records for "extend linear address". This is a value that is added to the front of 0000..FFFF to make a 32bit address (by default it is 0000). So to reach 0x112C720 it suggests your .hex file has an 04 record adding a 0x01120000 offset - that is 0112 as the payload of a type 04.

 

if your .hex really does have some data at such an address the next question is "why?". To detemine that I'd create and study a .map file. I see you are already creating hexclock.map - so take a look at that and see if there's anything listed there with a stupidly high address.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Great explanation on the differences between .data and .bss... and how it's handled. Very informative.

 

But unfortunately, I don't think you're right about the cause of the "free()" error. Note that the "free()" error message is in reference to avrdude's memory-space (running on the computer) rather than the memory-space of the AVR it's programming. So, even if the hex file was gigantic, avrdude should still be attempting to free() addresses that it previously malloc()ed...

 

I found this post as one of the *few* results regarding that error-message and avr-dude. And came across it from a different direction entirely. Rather'n *writing* a hex-file to an AVR, I'm trying to *read* the AVR's flash into a hex-file.

 

The result is a complete read of the flash-memory, and what appears to be a correct ihex file. But avr-dude aborts with:

*** Error in `avrdude': free(): invalid next size (normal): 0x09323798 ***
Aborted

 

I think this is a bug in avrdude.... it's been submitted at:

https://savannah.nongnu.org/bugs...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is a memory corruption somewhere in AVRdude. Probably a write on the heap corrupting the header of the next heap structure. This goes unnoticed until avrdude finishes and tries to free its resources. Since others can't seem to reproduce this issue it would be nice if you could post more extensive logs of the crash (like strack trace (with symbols, preferably)).

Last Edited: Sun. Aug 14, 2016 - 07:18 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

love to... how?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Try changing the make file like this:

 

avrdude_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\" -DDEBUG -g

libavrdude_a_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\" -DDEBUG -g

Then "make". This should give you a debuggable binary with symbols. See if the error still occurs and if so, it should print a stacktrace. If not, try running it inside gdb and it should break on the error and print more information.

 

edit: It's been a while since I've been on linux, but you might have to run

ulimit -c unlimited

as root to enable core dumping after a crash, too.

Last Edited: Sun. Aug 14, 2016 - 07:52 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, fresh avrdude-6.3 source-code folder:

$ ./configure

...

Configuration summary:
----------------------
DON'T HAVE libelf
DO HAVE    libusb
DO HAVE    libusb_1_0
DON'T HAVE libftdi1
DO HAVE    libftdi
DON'T HAVE libhid
DO HAVE    pthread
DISABLED   doc
ENABLED    parport
DISABLED   linuxgpio

 

$ make

builds

$ sudo make install

 

$ avrdude -c usbtiny -pm8515 -U flash:r:flash.hex:i

avrdude: AVR device initialized and ready to accept instructions

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

avrdude: Device signature = 0x1e9306 (probably m8515)
avrdude: reading flash memory:

Reading | ################################################## | 100% 8.57s

avrdude: writing output file "flash.hex"

avrdude: safemode: Fuses OK (E:FF, H:D9, L:F0)

avrdude done.  Thank you.

*** Error in `avrdude': free(): invalid next size (normal): 0x096dd770 ***
Aborted

 

 

Edit Makefile with your changes (unless I'm missing something, that just means adding '-DDEBUG -g' to avrdude_CPPFLAGS and libavrdude_a_CPPFLAGS, and NOT to CFLAGS):

 

$ make clean

$ make

/bin/bash ./ylwrap config_gram.y y.tab.c config_gram.c y.tab.h `echo config_gram.c | sed -e s/cc$/hh/ -e s/cpp$/hpp/ -e s/cxx$/hxx/ -e s/c++$/h++/ -e s/c$/h/` y.output config_gram.output -- bison -y -d
updating config_gram.h
/bin/bash ./ylwrap lexer.l lex.yy.c lexer.c -- flex  
make  all-recursive
make[1]: Entering directory '/home/meh/Desktop/avrdudeStuff/avrdude-6.3'
Making all in .
make[2]: Entering directory '/home/meh/Desktop/avrdudeStuff/avrdude-6.3'
gcc -DHAVE_CONFIG_H -I.  -DCONFIG_DIR=\"/usr/local/etc\" -DDEBUG -g  -Wall -Wno-pointer-sign -g -O2 -MT libavrdude_a-config_gram.o -MD -MP -MF .deps/libavrdude_a-config_gram.Tpo -c -o libavrdude_a-config_gram.o `test -f 'config_gram.c' || echo './'`config_gram.c
mv -f .deps/libavrdude_a-config_gram.Tpo .deps/libavrdude_a-config_gram.Po
gcc -DHAVE_CONFIG_H -I.  -DCONFIG_DIR=\"/usr/local/etc\" -DDEBUG -g  -Wall -Wno-pointer-sign -g -O2 -MT libavrdude_a-lexer.o -MD -MP -MF .deps/libavrdude_a-lexer.Tpo -c -o libavrdude_a-lexer.o `test -f 'lexer.c' || echo './'`lexer.c
mv -f .deps/libavrdude_a-lexer.Tpo .deps/libavrdude_a-lexer.Po
gcc -DHAVE_CONFIG_H -I.  -DCONFIG_DIR=\"/usr/local/etc\" -DDEBUG -g  -Wall -Wno-pointer-sign -g -O2 -MT libavrdude_a-arduino.o -MD -MP -MF .deps/libavrdude_a-arduino.Tpo -c -o libavrdude_a-arduino.o `test -f 'arduino.c' || echo './'`arduino.c
mv -f .deps/libavrdude_a-arduino.Tpo .deps/libavrdude_a-arduino.Po
gcc -DHAVE_CONFIG_H -I.  -DCONFIG_DIR=\"/usr/local/etc\" -DDEBUG -g  -Wall -Wno-pointer-sign -g -O2 -MT libavrdude_a-avr.o -MD -MP -MF .deps/libavrdude_a-avr.Tpo -c -o libavrdude_a-avr.o `test -f 'avr.c' || echo './'`avr.c
avr.c:38:0: warning: "DEBUG" redefined
 #define DEBUG 0
 ^
<command-line>:0:0: note: this is the location of the previous definition
mv -f .deps/libavrdude_a-avr.Tpo .deps/libavrdude_a-avr.Po
gcc -DHAVE_CONFIG_H -I.  -DCONFIG_DIR=\"/usr/local/etc\" -DDEBUG -g  -Wall -Wno-pointer-sign -g -O2 -MT libavrdude_a-avr910.o -MD -MP -MF .deps/libavrdude_a-avr910.Tpo -c -o libavrdude_a-avr910.o `test -f 'avr910.c' || echo './'`avr910.c
mv -f .deps/libavrdude_a-avr910.Tpo .deps/libavrdude_a-avr910.Po
gcc -DHAVE_CONFIG_H -I.  -DCONFIG_DIR=\"/usr/local/etc\" -DDEBUG -g  -Wall -Wno-pointer-sign -g -O2 -MT libavrdude_a-avrftdi.o -MD -MP -MF .deps/libavrdude_a-avrftdi.Tpo -c -o libavrdude_a-avrftdi.o `test -f 'avrftdi.c' || echo './'`avrftdi.c
<command-line>:0:7: error: expected identifier before numeric constant
avrftdi_private.h:25:25: note: in expansion of macro ‘DEBUG’
 enum { ERR, WARN, INFO, DEBUG, TRACE };
                         ^
avrftdi.c: In function ‘avrftdi_log’:
avrftdi.c:148:5: error: duplicate case value
     case DEBUG: avrdude_message(MSG_INFO, "D "); break;
     ^
avrftdi.c:146:5: error: previously used here
     case WARN:  avrdude_message(MSG_INFO, "W "); break;
     ^
avrftdi.c:149:10: error: ‘TRACE’ undeclared (first use in this function)
     case TRACE: avrdude_message(MSG_INFO, "T "); break;
          ^
avrftdi.c:149:10: note: each undeclared identifier is reported only once for each function it appears in
In file included from avrftdi.c:41:0:
avrftdi.c: In function ‘write_flush’:
avrftdi_private.h:37:35: error: ‘TRACE’ undeclared (first use in this function)
 #define log_trace(fmt, ...) __log(TRACE, fmt, ##__VA_ARGS__)
                                   ^
avrftdi_private.h:29:17: note: in definition of macro ‘__log’
     avrftdi_log(lvl, __func__, __LINE__, fmt, ##__VA_ARGS__); \
                 ^
avrftdi.c:489:2: note: in expansion of macro ‘log_trace’
  log_trace("Set pins command: %02x %02x %02x %02x %02x %02x\n",
  ^
avrftdi.c: In function ‘avrftdi_lext’:
avrftdi.c:916:15: error: ‘TRACE’ undeclared (first use in this function)
  if(verbose > TRACE)
               ^
avrftdi.c: In function ‘avrftdi_flash_write’:
avrftdi.c:1050:15: error: ‘TRACE’ undeclared (first use in this function)
  if(verbose > TRACE)
               ^
avrftdi.c: In function ‘avrftdi_flash_read’:
avrftdi.c:1143:15: error: ‘TRACE’ undeclared (first use in this function)
  if(verbose > TRACE) {
               ^
Makefile:1021: recipe for target 'libavrdude_a-avrftdi.o' failed
make[2]: *** [libavrdude_a-avrftdi.o] Error 1
make[2]: Leaving directory '/home/meh/Desktop/avrdudeStuff/avrdude-6.3'
Makefile:2030: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/home/meh/Desktop/avrdudeStuff/avrdude-6.3'
Makefile:671: recipe for target 'all' failed
make: *** [all] Error 2

Per:

avr.c:38:0: warning: "DEBUG" redefined
 #define DEBUG 0
 ^
<command-line>:0:0: note: this is the location of the previous definition

(Since when does -D NOT override a #define? I thought that was kinda the point!)

 

Edit avr.c, comment-out "#define DEBUG 0"

 

$ make clean

$ make

 

... pretty much the same...

 

 

 

Attempted change: -DDEBUG=1 -g

 

... pretty much the same...

 

Can't get it to build.

... we're kinda at my limit... debuggers and traces aren't amongst my usual tools.

 

 

$ gcc -v

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i586-linux-gnu/4.9/lto-wrapper
Target: i586-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.9.2-10' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.9 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-i386/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-i386 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-i386 --with-arch-directory=i386 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-targets=all --enable-multiarch --with-arch-32=i586 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=i586-linux-gnu --host=i586-linux-gnu --target=i586-linux-gnu
Thread model: posix
gcc version 4.9.2 (Debian 4.9.2-10)

 

Last Edited: Sun. Aug 14, 2016 - 08:31 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ericwazhung wrote:
(Since when does -D NOT override a #define? I thought that was kinda the point!)
Since always

-D functions as a #define .

If there is conflicting #define in the source, it is flagged.

As usual, identical #define's are allowed.

International Theophysical Year seems to have been forgotten..
Anyone remember the song Jukebox Band?