Menu

#3153 --debug produces same lable names for inline functions

open
None
other
5
2021-01-10
2020-11-14
Tony Pavlov
No

version:
--debug switch may produce duplicate labels for inline functions, because labels references to the file, that contain that inline function. linker reports error:

Multiple definition of C$inline.h$13$4_0$6
Multiple definition of C$inline.h$14$4_0$6

Source files attached.

SDCC : mcs51/z80/z180/r2k/r2ka/r3ka/gbz80/tlcs90/ez80_z80/z80n/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8/pdk13/pdk14/pdk15 4.0.4 #11925 (MINGW64)

commandline:

"c:\gb\gbdk\"bin/sdcc -mgbz80 --no-std-crt0 --fsigned-char --use-stdout -Wa-pog -DGB=1 -DGAMEBOY=1 -DINT_16_BITS -D__LCC__ --debug --nolospre -I"c:\gb\gbdk\"include -c src/a.c -o obj/lcc87400.o
"c:\gb\gbdk\bin/sdcc" -mgbz80 --no-std-crt0 --fsigned-char --use-stdout -Wa-pog -DGB=1 -DGAMEBOY=1 -DINT_16_BITS -D__LCC__ --debug --nolospre -I"c:\gb\gbdk\include" -c src/b.c -o obj/lcc87401.o
"c:\gb\gbdk\bin/sdcc" -mgbz80 --no-std-crt0 --fsigned-char --use-stdout -Wa-pog -DGB=1 -DGAMEBOY=1 -DINT_16_BITS -D__LCC__ --debug --nolospre -I"c:\gb\gbdk\include" -c src/main.c -o obj/lcc87402.o
"c:\gb\gbdk\"bin/sdldgb -n -i -j -k lib -l isr.lib -m -w -y -g .STACK=0xE000 -g .refresh_OAM=0xFF80 -b _DATA=0xc0a0 -b _CODE=0x0200 -k "c:\gb\gbdk\"lib/small/asxxxx/gbz80/ -l gbz80.lib -k "c:\gb\gbdk\"lib/small/asxxxx/gb/ -l gb.lib rom.ihx "c:\gb\gbdk\"lib/small/asxxxx/gb/crt0.o obj/lcc87400.o obj/lcc87401.o obj/lcc87402.o
1 Attachments

Discussion

  • Tony Pavlov

    Tony Pavlov - 2020-12-28

    can, please, someone look into this? because people get stuck with this, because they try to use debug adapter and gbdk library they are using contains inline functions for speed. thank you.

     
    • Philipp Klaus Krause

      Looking at the Changelog, there were only few entries recently. Looks like all developers are busy with stuff other than SDCC. And even if one finds time to look into SDCC, with SDCC being a free software project, we won't know what part of SDCC gets attention.
      Naturally, this bug is important to someone (otherwise it wouldn't have been reported), but so are other bugs. And of course, someone familiar with debug info would be most qualified to look into it. However, it would also be very helpful, if a newcomer could look into debug info and become familiar with that part of SDCC. SDCC does need more developers.

       
      • Tony Pavlov

        Tony Pavlov - 2020-12-28

        thank you, Philipp, that is clear to me. i just wanted to remind about this, because different users encounter that problem often and report that on discord, that's all. of course every developer is free to choose whether to pay this attention or not.

         
        • Maarten Brock

          Maarten Brock - 2020-12-30

          People who complain at any platform that is not supported by the developers are just whining away there frustration instead of trying to get something fixed. If they can't be bothered to report here, how can the developers know what is affecting them? Is signing up with SourceForge such a threshold that it stops those people?

          Tony, please redirect those people to report here.

           
          • Tony Pavlov

            Tony Pavlov - 2020-12-30

            because it is a GBDK discord and community, and SDCC, historically, is a part of GBDK. they complain about errors they get, when they try to use GBDK, to people who support GBDK. i happen to be a GBDK-2020 maintainer, so i mediate their troubles here. should i stop, for your peace of mind?

             
            • Maarten Brock

              Maarten Brock - 2020-12-30

              Certainly not. As I said, try to get these people to report here, if you want to convey the magnitude of the problem. I just don't want people to bark up the wrong tree.

               
              • Tony Pavlov

                Tony Pavlov - 2020-12-30

                just to be clear. 99% of original questions sounds like "i'm trying to debug my C code for game boy in vs.code and emulicious, but my program does not even compile". neither of that is a subject here, nevertheless, the problem is in SDCC. i took the trouble to investigate the problem and report it according to the local rules and templates. one really needs a desire for that.

                 
      • bbbbbr

        bbbbbr - 2021-01-01

        Hello- as mentioned in the other post, I help out some with GBDK-2020. I have looked into this some and here is what I've found. SDCC is a large codebase that I'm not very familiar with, so some of this may be incorrect. :)

        First thing I tried- can "static inline" be a workaround for the problem?

        It seemed that a possible workaround would be to make the inlined function "static inline" as a way to suppress the emission of global debug symbols and avoid the "multiple definition" problem. However that does not appear to work for "--debug".

        Making the inlined function "static inline" causes the inlined function to be generated standalone in the C source files (per code below), but it still emits global "--debug" C source symbols that point to the header file. Which results in an even larger number of Multiple Definition errors since now there is now the additional function emitting symbols and not just it's extracted body in other locations.
        SDCCast.c

        /* Temporary hack: always generate code for static inline functions. */
          /* Ideally static inline functions should only be generated if needed. */
          if (FUNC_ISINLINE (name->type) && !IS_EXTERN (fetype) && !IS_STATIC (fetype))
            goto skipall;
        

        Next, my understanding of what is happening in SDCC:

        Global debug C source symbols get emitted by cdbWriteCLine() in cdbFile.c. That function seems to try making them somewhat unique by appending the iCode level and block numbers. (Similar in a way to what fixupInlineLabel() in SDCCast.c does) The uniqueness works on a local source file level, but cannot guarantee that they are globally unique since the files are compiled individually and don't have access to a shared global state.

        Some alternatives to prevent the inline symbol collisions that come to mind are below. I'm not sure either are acceptable, but I'll mention them anyway. :)

        1. Suppress the symbols (debug C source symbols for inline C functions from other files) and don't emit them.

          • Problem: it seems non-trivial to create a flag and pass it all the way down from expandInlineFuncs() (attached to ast's?) so that it can be read from the iCode item in cdbWriteCLine() and used to suppress the symbol.
          • It would be easier to just check whether the filename from the iCode matches "fullSrcFileName" and not emit if it doesn't, but that would exclude all external code and that seems like it could be a problem and not desired behavior(?).
        2. Try to make the symbols (somewhat) globally unique. Perhaps something derived from "fullSrcFileName" could be appended to the end of the symbol. If not the filename itself, perhaps a short hash of the filename. I don't know enough about what is allowed in the debug symbol format to know if appending more is ok or not.

        I am happy continue looking into this if there are suggestions about a particular direction that seems viable to take.

         
      • bbbbbr

        bbbbbr - 2021-01-01

        One more question I had is why the z80 ports version of emitDebuggerSymbol() emits global debug symbols, while most of the other ports versions do not appear to (at least superficially). Perhaps it is just due to the different format for the port and isn't related to this?

        For example:

        void
        z80_emitDebuggerSymbol (const char *debugSym)
        {
          genLine.lineElement.isDebug = 1;
          emit2 ("%s !equ .", debugSym);
          emit2 ("!global", debugSym);
          genLine.lineElement.isDebug = 0;
        }
        

        Versus what is somewhat typical for other ports:

        pdk_emitDebuggerSymbol (const char *debugSym)
        {
          G.debugLine = 1;
          emit2 ("", "%s ==.", debugSym);
          G.debugLine = 0;
        }
        
         

        Last edit: bbbbbr 2021-01-01
        • Erik Petrich

          Erik Petrich - 2021-01-03

          Most of the other ports only generate code the ASXXXX assembler; it uses the double equals to both define the symbol and make it global in one step. The z80 port supports several assemblers, so the !equ and !global are macros that expand to the appropriate keywords and syntax for the selected assembler.

           
  • Tony Pavlov

    Tony Pavlov - 2020-12-28

    btw, this bug is very similar to this: https://sourceforge.net/p/sdcc/bugs/2591/

     
  • bbbbbr

    bbbbbr - 2020-12-31

    Hi, I also help out with GBDK-2020. I have been looking into this problem and will try to post some more detailed information shortly.

    In the mean time, here is a recent example of a user encountering the problem:

    [7:35 PM]Conway: What's strange is, these "Multiple definition" errors started when I removed an unneeded function from one of my .c files. The function was no longer being referenced anywhere, but removing it caused these errors. What's even stranger is, as long as I put the function back (even if it's empty) the errors go away. And even stranger to me than that, I can change the function name to anything and it still compiles. So, having an empty function, that isn't called anywhere, and can be named anything at all, makes everything compile fine. But if I remove that function, I get these errors.

    [7:38 PM] conway: So currently I have the following added to make it compile:
    void a() {
    }
    And adding or removing that empty function (or an empty function of any name at all) is all I have to do to make it compile or fail. No other changes.

    [913 PM]bbbbbr: it seems it may be related to duplicate symbols created by the how the move_sprite() etc functions are inlined. when the a() function is added you can see the difference in the symbols it's creating for move_sprite, and how the trailing numbers for the symbol between the two files no longer overlap

     

    Last edit: bbbbbr 2020-12-31
  • Erik Petrich

    Erik Petrich - 2021-01-01
    • assigned_to: Erik Petrich
     
  • Erik Petrich

    Erik Petrich - 2021-01-03

    [r12010] now omits line number debug data for inlined code, so this should fix the duplicate symbol linker errors for the non-static inline case.

    Sometimes there are duplicate line number debug data generated within a single file, whenever the generated code for a line is non-contiguous. This can happen even without inlining, but inlining makes this worse. At the moment, the assembler just keeps the last definition and discards the previous ones, so there's no error message, but the address for the line given in the debug data won't correctly point to the beginning of the line. I'm going to fix that next.

    The static inline case is much more difficult to resolve, so I'm saving that for last.

     
    • bbbbbr

      bbbbbr - 2021-01-03

      Erik,

      Thank you for the fix and for the explanation in your other reply! We'll try r12010 out when a snapshot build is up.

       
    • bbbbbr

      bbbbbr - 2021-01-10

      We've tested with a snapshot build and [r12010] appears to resolve the multiple definition errors as expected.

      I'm ok with either closing the ticket or leaving it open for the static inline case, whatever works best for you. (I could also open a separate ticket for static inline if that is preferred)

       

Log in to post a comment.

MongoDB Logo MongoDB