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.

Debug Server Scripting (DSS) - robust way of setting a breakpoint; reading a value



Hello!

I have two questions regarding Debug Server Scripting (DSS). First: it's really a nice way to automate things, e.g. loading and executing an executable with a standalone batch file which can included in an automatic build process.

Now I also want to automate execution profiling/ benchmarking and also verification, i.e. I use the profiling clock and a DSP-internal timer to count the clock cycles the algorithm takes. For verification purpose I also want to read back the results and compare against a gold model.

Robust way of setting breakpoints


You can set breakpoints using the activeDS.breakpoint.add() method. I have seen two options:

  • calling activeDS.symbol.getAddress("my_function") first on a function name (symbol)
  • calling activeDS.breakpoint.add("main.c", 76) to set a breakpoint at a specific line in a specific source code file.

Now assume that I have (at least partly) auto-generated code. I can use the getAddress("my_function"), but I want to stop before the function is called. With the current method it seems, that the function was already entered. In my belief the stack is then already set up. The problem is: the local variables of my calling function are out of scope, but I want to read or modify them before the function call.

Is there an easy way to accomplish this?

As an alternative I have tried using the second approach with setting the breakpoint at a specific line number. This sets a breakpoint before the function call, which is fine. The problem: I am not very flexible concerning code-generation here. That means the location of the function call will move within the source file and I'd have to modify the DSS script manually after every automatic code genration -- which would not be straight-forward.

Is there a way to determine the addresses of specific function calls? This would also be interesting if I called a function from different originating locations.

Reading a value

I want to read the value of a variable in the DSS script. I have figured out that this can be done using

  • activeDS.expression.evaluate("my_varname")

Is there an even smarter way to read a variable? Or a specifc memory location?

Thank you for your help.

Best regards,
Matthias

  • Hello Matthias,
    Can you create a label before the function call and the use symbol.getAddress on the label and set a breakpoint at the address? You'd run into scope issue where the label would have to be in scope when you try to get the address of the label. But depending on where your program is when you try to set the breakpoint, it may not be an issue.

    As for reading a variable, you can use symbol.getAddress to get the address of the variable and then memory.readWord (or readData) to get the value.

    Thanks
    ki
  • Hello Ki,

    thank you very much for your answer.

    Please take a look at the following code (screenshot):

    Let's say I want to read step_iterations. This is why I added profile_dummy_0() as a dummy function.

    When I now set a breakpoint using the function's name profile_dummy_0 I will run out of scope and the local variable step_iterations is no longer visible.

    How do you set a label? Inline assembly?

    Is there documentation for DSS besides the wiki, e.g. for looking up the data types of the methods "memory.readWord (or readData)".

    Best regards,
    Matthias

  • Matthias Weber said:
    How do you set a label? Inline assembly?

    I was just thinking of using a standard C label right before the function call like:

    mylabel:

    profile_dummy_0();

    And set the breakpoint at the address of mylabel.

    Matthias Weber said:
    Is there documentation for DSS besides the wiki, e.g. for looking up the data types of the methods "memory.readWord (or readData)".

    Besides the wiki, the API documentation would have the information you are looking for. Admittedly it is not the best laid out document but all the information you are looking for should be there:

    <CCS INSTALL DIR>/ccsv6/ccs_base/scripting/docs/DS_API/index.html

    Thanks

    ki

  • Hi Ki,

    thank you for your response and pointing me to labels.

    When using labels I get the following warnings:

    Description Resource Path Location Type

    #179-D label "labelname" was declared but never referenced main.c /projectname line 1337 C/C++ Problem

    It is true that the labels are never referenced. Can this warning be ignored?

    Will those label symbols be optimized out? And if, how can I prevent them from being optimized out?

    Regarding the use of expression.evaluate what does happen in the background?

    Will it be faster to use memory.readWord/.readData instead? If it was used on local variables then I'd have to call symbol.getAddress each time before I call the memory method again, right? Are there any other problems related to the scope of variables?

    Thank you,

    Matthias

    PS: The E2E forum regularly crashes my Internet Explorer and I need to retype the forum posts.

  • Matthias Weber said:

    When using labels I get the following warnings:

    Description Resource Path Location Type

    #179-D label "labelname" was declared but never referenced main.c /projectname line 1337 C/C++ Problem

    It is true that the labels are never referenced. Can this warning be ignored?


    Unless you actually use the label (like with a goto statement), they will be unused and not impact your code. The warning can be ignored unless....

    Matthias Weber said:
    Will those label symbols be optimized out? And if, how can I prevent them from being optimized out?

    ...they get optimized out (when optimization levels are increased) because they are unused. I just tried it and yes, cranking up optimization will remove unused labels. And I was not able to find a way to prevent it from being optimized out.


    hence I'm not sure if labels are the way to go unless you plan on using it only with code compiled without optimization enabled.


    I was brainstorming with a colleague of mine and unfortunately I don't think there is a clean and easy way to achieve what you wish to do. One idea was to get the address of the start of the function that you wish to set the breakpoint in and then you can set a breakpoint on that address + offset, with the offset being where inside the function you wish to set the breakpoint on. However that offset would change if the contents of that function itself is modified. How viable this option is would be if the contents of that function can change or not. Another idea is to have your script automatically parse the source file and then find the line number it needs to set the breakpoint on in the latest iteration of that source file. Another is to parse OFD generated output and get the address that way. None of them is a very "clean" solution I'm afraid

    Matthias Weber said:
    Regarding the use of expression.evaluate what does happen in the background?

    It basically calls the GEL expression evaluator for that expression:

    http://processors.wiki.ti.com/index.php/Debug_Server_Scripting#Using_GEL

    Matthias Weber said:
    Will it be faster to use memory.readWord/.readData instead? If it was used on local variables then I'd have to call symbol.getAddress each time before I call the memory method again, right? Are there any other problems related to the scope of variables?

    I don't known if it will be faster. Many DSS APIs simply call GEL under the hood anyway. But DSS APIs are guaranteed synchronous and you can properly catch and handle exceptions hence we recommend using it over direct GEL.

    But yes, you'd need to get the address first before using those APIs.


    Hope this helps

    ki

  • Update - my colleague showed me a trick with putting a label inside an asm statement:

    asm(" .global label_name_here\nlabel_name_here: ");

    profile_dummy_0();

    You can then get the address of "label_name" and set a breakpoint on that address. That label will be preserved even with optimization.

    Thanks

    ki

  • Hello Ki,

    thank you and your colleagues very much for putting so much effort into your answers. They are really helpful and highly appreciated.

    Have a nice weekend,
    Matthias