AVR simulator as aid tool for debugging code

Oh… nice! So you were able to make a windows binary… I was having trouble as stuff was missing, sites with pre-built libraries no longer having valid SSL certificates, yada, yada. Linux was straightforward, just wasn’t what I wanted to try out…

And to boot, I was just going to try this, and now VSCode 1.45.0 is giving me The task provider for "C/C++" tasks unexpectedly provided a task of type "shell". FFS can’t VSCode (or is it the C/C++ extension this time?) do just one update that doesn’t break platformIO? :rofl: :rofl:

So, PlatformIO is still working dispute that error… but I get this… apparently I don’t qualify! :stuck_out_tongue_winking_eye:

PackageManager: Installing tool-simavr @ ~1.6.0
Error: Could not find a version that satisfies the requirement '~1.6.0' for your system 'windows_x86'
The terminal process terminated with exit code: 1

@valeros, is this package compatible only with x64?

@pfeerick, does this Windows x64 package work for you? Service End for Bintray, JCenter, GoCenter, and ChartCenter | JFrog

It looks like VSCode bug

Thanks for linking the github issue. It looks like the fix is pending, I replied further on the github issue just now.

That simavr executable runs on my system… which is x64 bit…

image

so not sure what when wrong there! :open_mouth:

Downloaded the package, poked

    "system": [
        "windows",
        "windows_amd64",
        "windows_x86"
    ],

in instead of

    "system": [
        "windows_amd64"
    ],

into the package.json and it’s running nicely so far. Just a stupid simple test…

1 Like

@valeros Some news. I’ve started to dissect simavr code, especially the code related to the GDB server. After sniffing an exchange between simavr and GDB I found that one version of avr-gdb sends the vFlashErase command while the other doesn’t, and as simavr doesn’t support said that command it triggers the error you found.

The workaround would be to find a way to avoid sending that command for this target, at least until it gets implemented. I will keep reviewing that code and maybe send PR if the author doesn’t fix it.

Edit: the load command isn’t needed if the .elf file is passed as argument to simavr

simavr -g -f <freq> -m <model> firmware.elf
1 Like

@valeros
The biggest difference between both GDB compile flags is the inclusion of the expat library, and the reason why it is used in GDB is explained here.

To be able to write into flash memory, GDB needs to obtain a memory map from the target.

Also:

GDB assumes that areas of memory not covered by the memory map are RAM, and uses the ordinary ‘M’ and ‘X’ packets to write to addresses in such ranges.

So not including that lib would make avr-gdb unable to use of all the vFlash commands, or make it believe that everything is RAM, which is exactly what I captured with the sniffer. The version with expat tried to use vFlash commands while the version without it used only ‘M’ commands and the later are supported by simavr.

Could you provide a PR to simavr repository with a fix? We can rebuild binary for macOS from your branch. Thanks!

We use official Microchip toolchain to keep compatibility with Arduino projects. I recommend to keep the same official toolchains for all systems but add fix to simavr which will just ignore this “Erase” command.

1 Like

Thanks! Fixed! :blush:

1 Like

@ivankravets I’ve started to work on that, meanwhile you could try the other workaround without having to recompile anything. That way we can start testing on OSX before the patch is ready.

simavr -g -f <freq> -m <model> firmware.elf

@ivankravets @valeros I’ve just uploaded a patch for issue #371 to my fork, please test if it works on OSX.

The fix consists of faking the memory map reporting the Flash section as RAM which forces avg-gdb to use only the M command instead of vFlashErase, vFlashWrite and vFlashDone.

I’ve tested with both my versions of avr-gdb and the load command doesn’t trigger that error anymore.

Nevertheless, I will keep working on this and also on the issue #370, so the commands monitor reset and monitor halt get supported too.

2 Likes

@ivankravets @valeros
Done, I’ve just added a fix for issue #370. Now pio_reset_halt_target and pio_reset_run_target can be populated like this:

  define pio_reset_halt_target
      monitor reset
  end
  define pio_reset_run_target
      monitor halt
  end
  target remote :$DEBUG_PORT
  $LOAD_CMDS
  $INIT_BREAK

About the fix, monitor reset will put the processor to a initial state and pause, while monitor halt will gracefully terminate all execution and close the program.

Please, rebuild from my fork and test if there are any other bugs.

1 Like

@msquirogac! Many thanks for such a great contribution, it works much better on OS X, so we’ve used your fork as the source for tool-simavr package! One thing though, it looks like GDB is not able to produce disassembly for the uploaded firmware, on OS X GDB complains:

Unable to disassemble: Cannot access memory at address 0x800900 (from data-disassemble -s 0x000008b8 -e 0x0000091c -- 2)

on other platforms it mostly returns NOPes:

0x008007d2: 00 00           	nop
0x008007d4: 00 00           	nop

Any ideas?

Anyway, thanks again for efforts!

@valeros Maybe another gdb command without support.
What are the commands related to the disassemble function or at least the ones that vscode tries to use?

For example you can run in the CLI mode:

disassemble main

in my case the output is :

(gdb) disassemble main
Dump of assembler code for function main:
   0x000008ca <+0>:     .word   0xffff  ; ????
   0x000008cc <+2>:     .word   0xffff  ; ????
   0x000008ce <+4>:     .word   0xffff  ; ????
   0x000008d0 <+6>:     .word   0xffff  ; ????
   0x000008d2 <+8>:     .word   0xffff  ; ????
   0x000008d4 <+10>:    .word   0xffff  ; ????
   0x000008d6 <+12>:    .word   0xffff  ; ????
   0x000008d8 <+14>:    .word   0xffff  ; ????
   0x000008da <+16>:    .word   0xffff  ; ????

or, for example, GDB MI command:

data-disassemble -s 0x000008ca -e 0x000008dc -- 2

@valeros
This is the procedure to launch the debug session on CLI mode, right?
Could you upload the source code you are using? My demo returns this for disassemble main

0x0000044c < 0>: call 0x220 ; 0x220
0x00000450 < 4>: call 0x38c ; 0x38c
0x00000454 < 8>: call 0x358 ; 0x358
0x00000458 < 12>: ldi r24, 0x00 ; 0
0x0000045a < 14>: ldi r25, 0x00 ; 0
0x0000045c < 16>: or r24, r25
0x0000045e < 18>: breq .-12 ; 0x454 <main 8>
0x00000460 < 20>: call 0 ; 0x0 <__vectors>
0x00000464 < 24>: rjmp .-18 ; 0x454 <main 8>

This is the procedure to launch the debug session on CLI mode, right?

Yes, that’s one of the options or you can type commands directly in the debug console.

My demo returns this for disassemble main

I see, it looks like the load command is mandatory even if the firmware didn’t change.

But what’s interesting is that when I specify a memory range it still returns NOPes, e.g.:

(gdb) disassemble main
Dump of assembler code for function main:
=> 0x000008ca <+0>:     call    0x24e   ;  0x24e <init>
   0x000008ce <+4>:     call    0x74a   ;  0x74a <setup>
   0x000008d2 <+8>:     call    0x7d2   ;  0x7d2 <loop>
   0x000008d6 <+12>:    call    0x732   ;  0x732 <serialEventRun>
   0x000008da <+16>:    rjmp    .-10            ;  0x8d2 <main+8>
End of assembler dump.
(gdb) disassemble 0x000008ca,0x000008da
Dump of assembler code from 0x8008ca to 0x8008da:
   0x008008ca:  nop
   0x008008cc:  nop
   0x008008ce:  nop
   0x008008d0:  nop
   0x008008d2:  nop
   0x008008d4:  nop
   0x008008d6:  nop
   0x008008d8:  nop
End of assembler dump

@valeros
Look at the addresses. While you ask for 0x000008ca, which is in the flash section so is good, GDB returns 0x8008ca. That 8 shouldn’t be there and the returned memory is outside the program region. By default that memory is empty, that’s why we have nop.
I haven’t figured why GDB is doing that yet. Do you have any idea?

Edit: I’ve found and old comment from the author himself related to this problem. That lead me to research about the memory mapping in avr-gdb and looks like there is a very well known bug. I found a patch but it never got into avr-gdb mainline.

@ivankravets
We need that fix to get the disassemble command working properly. Would it be possible to recompile avr-gdb with that patch? As this only affects avg-gdb it shouldn’t have any effect over avr-gcc, so Arduino compatibility should stay the same.

2 Likes

Could someone helps us with updated binaries?

This patch definitely works. I compiled GDB 9.1 from Index of /gnu/gdb, applied the source change, compiled (./configure --target=avr --prefix=<some_local_install_dir> && make && make install procedure) and it goes from previously

disassemble main
Dump of assembler code for function main:
   0x00000496 <+0>:     call    0x280   ;  0x280 <init>
   0x0000049a <+4>:     call    0x3d6   ;  0x3d6 <setup>
   0x0000049e <+8>:     call    0x3b8   ;  0x3b8 <loop>
   0x000004a2 <+12>:    ldi     r24, 0x00       ; 0
   0x000004a4 <+14>:    ldi     r25, 0x00       ; 0
   0x000004a6 <+16>:    or      r24, r25
   0x000004a8 <+18>:    breq    .-12            ;  0x49e <main+8>
   0x000004aa <+20>:    call    0       ;  0x0 <__vectors>
   0x000004ae <+24>:    rjmp    .-18            ;  0x49e <main+8>
End of assembler dump.
{"token":55,"outOfBandRecord":[],"resultRecords":{"resultClass":"done","results":[]}}
disassemble 0x496,0x4ae
Dump of assembler code from 0x800496 to 0x8004ae:
   0x00800496:  nop
   0x00800498:  nop
   0x0080049a:  nop
   0x0080049c:  nop
   0x0080049e:  nop
   0x008004a0:  nop
   0x008004a2:  nop
   0x008004a4:  nop
   0x008004a6:  nop
   0x008004a8:  nop
   0x008004aa:  nop
   0x008004ac:  nop
End of assembler dump.

to

disassemble 0x496,0x4ae
Dump of assembler code from 0x496 to 0x4ae:
   0x00000496 <main+0>:	call	0x280	;  0x280 <init>
   0x0000049a <main+4>:	call	0x3d6	;  0x3d6 <setup>
   0x0000049e <main+8>:	call	0x3b8	;  0x3b8 <loop>
   0x000004a2 <main+12>:	ldi	r24, 0x00	; 0
   0x000004a4 <main+14>:	ldi	r25, 0x00	; 0
   0x000004a6 <main+16>:	or	r24, r25
   0x000004a8 <main+18>:	breq	.-12     	;  0x49e <main+8>
   0x000004aa <main+20>:	call	0	;  0x0 <__vectors>
End of assembler dump.

Though I seem to have made some mistake while compiling regarding python because GDB keeps complaining about

Python Exception <type 'exceptions.NameError'> Installation error: gdb._execute_unwinders function is missing: 

so it doesn’t make sense to share the binary. But the patch is correct.

2 Likes