Quantcast
Channel: User Jeremy - Stack Overflow
Viewing all articles
Browse latest Browse all 46

GCC, GDB, and is_stmt

$
0
0

I'm using GNU Arm Embedded Toolchain 10.3 to cross-compile for a Cortex-M0+ target, and using the accompanying GDB to debug.

I want to set a breakpoint on the following line of code:

    if (mPendingMessageIndex == 0)    {        // Start a new pending message-->     mPendingMessage[0] = extracted;        // Check for running status first        if (isChannelMessage(getTypeFromStatusByte(mRunningStatus_RX)))        {            // Only these types allow Running Status

This is line 818 of the file, so in GDB, while stopped at a nearby line, I type:

b 818

And I get the response:

Breakpoint 2 at 0x2000cc1c: file lib/arduino_midi_library/src/MIDI.hpp, line 1090.

Now, this is an inlined template method, and I appreciate that inlining can complicate matters, even when compiling (as I am) with -Og -ggdb3.But line 1090 is in a separate method that's not invoked from here.

So... really?

Disassembly of the ELF file shows this:

            if (mPendingMessageIndex == 0)    2000bed0:   6e63        ldr r3, [r4, #100]  ; 0x64    2000bed2:   2b00        cmp r3, #0    2000bed4:   d000        beq.n   2000bed8 <midi::MidiInterface<usbMidi::usbMidiTransport, midi::DefaultSettings, midi::DefaultPlatform>::parse()+0x3c>    2000bed6:   e0b6        b.n 2000c046 <midi::MidiInterface<usbMidi::usbMidiTransport, midi::DefaultSettings, midi::DefaultPlatform>::parse()+0x1aa>    lib/arduino_midi_library/src/MIDI.hpp:818            mPendingMessage[0] = extracted;--> 2000bed8:   335b        adds    r3, #91 ; 0x5b    2000beda:   54e1        strb    r1, [r4, r3]    lib/arduino_midi_library/src/MIDI.hpp:821            if (isChannelMessage(getTypeFromStatusByte(mRunningStatus_RX)))    2000bedc:   3b02        subs    r3, #2    2000bede:   5ce2        ldrb    r2, [r4, r3]

Line 818 corresponds to address 0x2000bed8 so in GDB I type:

b *0x2000bed8

And get:

Breakpoint 3 at 0x2000bed8: file lib/arduino_midi_library/src/MIDI.hpp, line 818.

So GDB can map the address to the line, but not vice versa.It's a major pain in the arse, but I can work with it - so I do.

But curiosity gnaws at me - so after a lot more rooting around I eventually find in the GDB sources:

static intfind_line_common (struct linetable *l, int lineno,                  int *exact_match, int start){    ...      /* Ignore non-statements.  */      if (!item->is_stmt)        continue;

So it looks like GDB will only set breakpoints on lines where the is_stmt flag is set in the DWARF info.

And sure enough, readelf -wL tells me that that line is not marked as is_stmt (indicated by 'x'):

    USB-MIDI.h                                   130          0x2000beca       1       x    USB-MIDI.h                                   130          0x2000beca       2    lib/arduino_midi_library/src/MIDI.hpp:    MIDI.hpp                                     812          0x2000beca       3    MIDI.hpp                                     815          0x2000bed0    MIDI.hpp                                     815          0x2000bed2--> MIDI.hpp                                     818          0x2000bed8    MIDI.hpp                                     821          0x2000bedc    MIDI.hpp                                    1228          0x2000bee0               x

readelf also tells me that no other line of code corresponds to address 0x2000bed8, and no other address corresponds to line MIDI.hpp:818.

So... I guess this boils down to two questions.

  • Why would GCC not mark such an unambiguous location as is_stmt?
  • If GCC can be expected to produce such output, why does GDB so naively ignore lines not marked is_stmt?

And the bonus question is:

  • Is there a way around this?

NB: I've experimented with compiler switches such as -gstatement-frontiers and -ginline-points, and they have no effect.

EDITED TO ADD:

readelf further indicates that large swathes of templated code from this file lack is_stmt flags. Literally hundreds of lines, corresponding to scores of statements, mostly consisting of switch statements and assignments, producing 250 line table records in the readelf output - of which ten are marked is_stmt, and precisely all of those correspond to inline expansions of helper functions.


Viewing all articles
Browse latest Browse all 46

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>