This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/TM4C123GE6PM: How to "attach" source code when debugging a "binary blob" of instructions?

Part Number: TM4C123GE6PM


Tool/software: Code Composer Studio

I have an application which consists of  a CCS project and a separately compiled ARM binary which my code in CCS jumps into at run time.

During JTAG debug I can step through the source code which is included in the CCS project (as normal), but once execution enters the "binary blob", of course there is no source code and I only can read the disassembled ASM.

I do have the source code for the "binary blob". But how can I have this "external source code" automatically tied to the "binary blob" at debug time? What are the prerequisites for that?

  • Hi Aaron,

    You need to load the debug symbols for the compiled ARM binary you wish to debug. For you CCS project, I assume you are loading a *.out file. This has both the binary and debug symbols in it. 

    Note that even of you do have the debug symbols, but that binary was compiled with optimization enabled, it can impact your debug visibility:

    http://processors.wiki.ti.com/index.php/Debug_versus_Optimization_Tradeoff

    Thanks

    ki

  • Hi Ki-Soo, appreciate the reply.

    I discovered that during debug, I have the ability to "add symbols" using the Load button menu (my .elf file for the binary blob), and also I can add a source code directory in the debug configuration. But that doesn't seem to be enough; when I step through the ASM there is no source code that comes up as it does for the regular CCS code.

    So basically I have:
    myapp.bin (e.g stripped of all symbols)
    myapp.elf (with symbols)
    myapp.c

    (1) myapp.bin is loaded from external SPI Flash chip on my target board into internal Tiva RAM, and it is what I am stepping through. Should it actually be myapp.elf loaded into microcontroller RAM if I want to see source code? E.g. I'm not clear if the symbols need to be resident on the target hardware, or the PC, or both. Unfortunately, the ELF is too large for target RAM so I hope that's not the case....

    (2) When I click "add symbols" I should select myapp.elf? Is "code offset" supposed to be the address at which myapp.bin/myapp.elf is running from in RAM?

    (3) Does the external source code dir have to have the exact same path structure as the original build directory (it was build on a different machine) or can I basically just dump any *.c file into the source code dir and it will automatically be picked up?

  • Aaron Mills said:
    Should it actually be myapp.elf loaded into microcontroller RAM if I want to see source code? E.g. I'm not clear if the symbols need to be resident on the target hardware, or the PC, or both. Unfortunately, the ELF is too large for target RAM so I hope that's not the case....

    The *.elf is (assuming it is a valid elf file) basically the *.bin + DWARF debug symbols. When you tell CCS to load the *.elf file, it will load the *.bin part on to target memory and the DWARF debug symbols to the debugger (host memory). It uses information in the debug symbols to tell the debugger where in target memory the *.bin part is to be loaded to target memory. Hence if myapp.bin is already loaded via external means (as is your case), then you just need to add the DWARF symbols to the debugger via "add symbols" option. This should have the same effect as if you just loaded the *.elf file.

    Aaron Mills said:
    (2) When I click "add symbols" I should select myapp.elf? Is "code offset" supposed to be the address at which myapp.bin/myapp.elf is running from in RAM?

    Yes you would load the symbols for myapp.elf by selecting it when using the "add symbols" option. This will tell the debugger to just load the symbols part of myapp.elf and ignore the binary load part. As for code offset, the debugger will read the debug symbols in myapp.elf to determine the offset. You only need to provide the offsets when adding symbols from individual object files.... except (see below)

    Now there is one big caveat here. When the *.elf file was built, the linker options specified where in target memory the binary part will be loaded and executed. This is the information used by the debugger to know where to load the binary code AND also how to associate the code in target with source level debugging. One issue that happens is if people then relocate the code to another part of memory after CCS loaded it OR if CCS/debugger is NOT used to load the target binary but via some other mechanism (like in your case). Then what happens is that the code is being run from a location that the debugger is not expecting (based on the loaded debug symbols). Hence you will not have correct debug visibility for that code.

    My question is - is that the case for your environment? Is the code being run from a location that is different then what was specified at link time?

    Aaron Mills said:
    (3) Does the external source code dir have to have the exact same path structure as the original build directory (it was build on a different machine) or can I basically just dump any *.c file into the source code dir and it will automatically be picked up?

    The debugger will look for source files in locations specified in the debug symbols and also via debug source search paths. For the former, those locations are based off relative paths from the location of where the *.out file was generated. Debug source search paths can specified in the configuration properties. If the debugger can't find a source file, it will prompt you and you have the option of telling it where it is:

    http://software-dl.ti.com/ccs/esd/documents/users_guide/sdto_ccs_debug-handbook.html#debugging-library-code

    If you are never prompted, then it does not have any source code correlation for the address.

    There are other considerations like optimization and such but my current biggest question is what I mentioned in #2.

    Thanks

    ki

  • Hi, with this understanding in mind, I went back and studied my elf file with more scrutiny. Turns out, there was a parameter in the original Makefile which was actually stripping the debug symbols.

    After reproducing the elf, I was able to follow the process you described, while providing an offset equal to the offset in RAM, and the source code came up at debug time. 

    Thanks for the help!

  • Glad to hear your resolve the issue! Yep, you need those debug symbols. And even if you have them, note that if you have high optimization enabled, that can also impact your source level debug experience.

    Just out of curiosity, what build tools did you use to generate the *.elf file? GCC?

    Thanks
    ki
  • Indeed, even though the source came up, debugging was a bit jumpy. Need to check my optimization setting. Within CSS, I use the TI compiler; for the external elf I'm using GCC.

  • To find the right balance between optimization and debug experience, check out the below article:
    processors.wiki.ti.com/.../Debug_versus_Optimization_Tradeoff

    Thanks
    ki