Floating Point Registers and gdb

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Pava_1191361
Level 3
Level 3
First like received First like given Welcome!

Recently I ran into an issue, where I passed a floating point variable over the stack to a function:

void WriteBuffer(sampleContext_t* pContext, float value);

The call was made in an ISR, and I was able to set a breakpoint on the function, which was hit.

void SAR_Interrupt(void)

{

     <code using several floating point variables>

     ...

     WriteBuffer(pContext, fVal);

}

The moment I tried to step into the function call, the debugger ended with:

~"/home/build/work/GCC-5-0-build/src/gdb/gdb/regcache.c:176: internal-error: register_size: Assertion `regnum >= 0 && regnum < (gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch))' failed.\nA problem internal to GDB has been detected,\nfurther debugging may prove unreliable.\nQuit this debugging session? "

~"/home/build/work/GCC-5-0-build/src/gdb/gdb/regcache.c:176: internal-error: register_size: Assertion `regnum >= 0 && regnum < (gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch))' failed.\nA problem internal to GDB has been detected,\nfurther debugging may prove unreliable.\nCreate a core file of GDB? "

Error: dbg.M0015: Debugger exited unexpectedly during run.  Encountered error (GDB encountered an error and had to close.  See output window for more information. See output window for more information.)

CANCEL

I did found a couple of work-arounds:

1.  Eliminate (simplify) the <code using several floating point variables>

2.  Change void WriteBuffer(sampleContext_t* pContext, float value);

            into void WriteBuffer(sampleContext_t* pContext, float* value);

    which now passes a pointer to the value rather than the value it self over the stack.

But why did this debugger crash happen?

Interesting enough I discovered a thread regarding this similar error on a NXP forum (https://community.nxp.com/thread/389948​), which lead me to believe that this has to do with the floating point registers of the ARM cortex M4 processor, see https://www.sciencedirect.com/topics/computer-science/floating-point-register, Which states:

"S0 to S15 are caller saved registers. So if a function A calls a function B, function A must save the contents of these registers (e.g., on the stack) before calling function B because these registers can be changed by the function call (e.g., return result). S16 to S31 are callee saved registers. So if a function A calls a function B, and function B needs to use more than 16 registers for its calculations, it must save the contents of these registers (e.g., on the stack) first, and must restore these registers from the stack before returning to function A.The initial values of these registers are undefined."

My assumption is that the gdb in the PSoC Creator does not support S16..S31, and as soon a this condition occurs (which is only when debugging code that uses these registers) the debugger bows out ungracefully.... 

Now to the point: When debugging there is a register window (Toolbar => Debug => Windows => Registers) which only shows the "Regular" registers, but NOT the floating point (S1.. S31) registers...

How to view those floating point registers?

0 Likes
1 Solution

Hi,

You are missing the point here. The posted is an contrived example to force the compiler to use the extra set of floating point registers that the M4 processor has  (S16 .. S31), which will happen only when numerous floating point operations are involved. I am aware that there are numerous ways of solving this particular issue, the point is, that there's a bug in the debugger, which impacts at any location that uses the S16.. S31 registers. Besides the fact that PSoC does not have the ability to show those registers, it is quite a nuisance if in some particular instances the debugger just quits on you, just by setting a breakpoint at the wrong location....

But thanks anyway for looking into this, it's good to know it didn't just happen on my machine.

View solution in original post

0 Likes
12 Replies
DheerajK_81
Moderator
Moderator
Moderator
First comment on KBA First comment on blog 5 questions asked

Looks like the GDB Server doesn't return anything based on the error when floating point registers are being accessed and hence GDB fails in this fashion. I have passed this query to the internal software team for evaluation.

Can you please attach your project so that we can get more insight on the issue?

Thank you for your interest in Cypress Products.

Regards,
Dheeraj

0 Likes
DheerajK_81
Moderator
Moderator
Moderator
First comment on KBA First comment on blog 5 questions asked

I checked with the internal team and here's what they had to say. PSoC Creator implements the GDB Server using cypsocdebugger which does not have support for floating-point registers. This is why you are observing the error.

Please make use of the workarounds you rightly mentioned to avoid this issue.

Regards,

Dheeraj

0 Likes

One thing is not supporting floating point registers, which is just inconvenient, another thing is that the application halts when a breakpoint is set at the wrong position, which is clearly a bug. To me it looks like that gdbarch_num_pseudo_regs(gdbarch) was set incorrectly (as the correct number of floating point registers are not accounted for), which causes the assert error. I will try to make a short demo program that causes this.

0 Likes

Yes please share the project. It will help us in our evaluation

Regards,

Dheeraj

0 Likes
lock attach
Attachments are accessible only for community members.

Hi,

I managed to create a project in which the error occurs consistently. It's a bit tricky to have code that enforces the compiler to generate the offending code.

Used is PSoC creator 4.3, and all the code is in main_cm4.c

The  code compiles and runs on a CY8CKIT-062-BLE, and an output pin is configured in the ISR (which light up the red LED on the board).

Compile and Run the code. (Target CM4 with the debugger).

The red led will turn on, identifying that sample ISR is being visited.

Place a breakpoint at line 57:

   WriteToBuffer(pContext, adcSample);

When it hits, attempt to step into the method (F11) and the Debugger will end "unexpectedly".

pastedImage_3.png

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

I just saw your sample.

Although Cy_SAR_GetResult16() returns an int16_t, you are passing it as a float.

So I changed following 3 points

================

void WriteToBuffer(ChannelContext_t * pContext, int16_t adcSample) // adcSample is now int16_t <---

{

    pContext->dataBuffer[pContext->index++] = (float)adcSample; // converting adcSample to a float <---

    pContext->pLut++;

    if (pContext->index >= 16)

    {   pContext->index = 0;

        pContext->pLut = &LutTable[0];

    }

}

void CalcAndWriteToBuffer(ChannelContext_t * pContext, int16_t adcSample) // adcSample is now int16_t <---

{

    // Have some (floating point related) math here.

    float f1 =  1.0 / 8.0 * (adcSample + pContext->dataBuffer[pContext->index]);

    pContext->Xa += f1 * (*pContext->pLut);

    pContext->Xb -= f1 * 2.0 * (*pContext->pLut);

 

    pContext->result = pContext->Xa / 0.5 * sqrtf(pContext->Xa * pContext->Xa + pContext->Xb * pContext->Xb);

    // Set a breakpoint here on WriteToBuffer. Then Step try to step into the method (F11): PSoC Creator Error dbg.M0015

    WriteToBuffer(pContext, adcSample);

}

================

And it seems working OK.

So my conclusion (which may be wrong but),

the debugger was not happy receiving an int16_t data as a float.

moto

0 Likes

Hi,

You are missing the point here. The posted is an contrived example to force the compiler to use the extra set of floating point registers that the M4 processor has  (S16 .. S31), which will happen only when numerous floating point operations are involved. I am aware that there are numerous ways of solving this particular issue, the point is, that there's a bug in the debugger, which impacts at any location that uses the S16.. S31 registers. Besides the fact that PSoC does not have the ability to show those registers, it is quite a nuisance if in some particular instances the debugger just quits on you, just by setting a breakpoint at the wrong location....

But thanks anyway for looking into this, it's good to know it didn't just happen on my machine.

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Pava-san,

I'm sorry for my short-site.

> But thanks anyway for looking into this, it's good to know it didn't just happen on my machine.

Yes, I could re-bug the code just returning the type of adcSample in WriteToBuffer from uint16_t to float.

> the point is, that there's a bug in the debugger,

I wonder if this should be fixed by Cypress, GNU, or Arm.

May be submitting this bug report to GNU's forum or ARM developer Community gives us earlier result.

GNU Toolchain | 5-2016-q2-update – Arm Developer

Best Regards,

26-Apr-2020

Motoo Tanaka

0 Likes

As far as I can see, it's not an ARM issue, nor a GDB issue. When I look at the error:

Assertion `regnum >= 0 && regnum < (gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch))' failed

It seems that an assertion failed. Given that GDB has just methods to specify those values:

     extern void set_gdbarch_num_regs (struct gdbarch *gdbarch, int num_regs);

     extern void set_gdbarch_num_pseudo_regs (struct gdbarch *gdbarch, int num_pseudo_regs);

(see binutils-gdb/gdbarch.h at master · redox-os/binutils-gdb · GitHub ),

it looks to me that the component using GDB has incorrectly specified those for the M4 processor.

Looking at the previous (lengthy) thread I mentioned before (https://community.nxp.com/thread/389948),

it actually stated a solution, where PEMicro was confronted with the same issue:

"I heard back from PEMicro and fix should be next week.  Exact wording:

We will post a new release of our GDB server mid-next week to our update site which has this fix. "

So my money is on the software component in PSoC creator that interacts with the GDB debugger (whether that is GDB server or not).

On the other hand, the link you mentioned refers to a pretty dated toolchain. Perhaps an update there could resolve the issue as well?

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

First of all, let me sincerely apologize to you.

I'm slow and finally read the earlier discussion and the NXP thread.

You wrote

> and as soon a this condition occurs (which is only when debugging code that uses these registers) the debugger bows out ungracefully....

> Now to the point: When debugging there is a register window

> (Toolbar => Debug => Windows => Registers) which only shows the "Regular" registers,

> but NOT the floating point (S1.. S31) registers...

> How to view those floating point registers?

Cypress wrote

> I checked with the internal team and here's what they had to say.

> PSoC Creator implements the GDB Server using cypsocdebugger

> which does not have support for floating-point registers.

> This is why you are observing the error.

> Please make use of the workarounds you rightly mentioned to avoid this issue.

and

>  To me it looks like that gdbarch_num_pseudo_regs(gdbarch) was set incorrectly (as the correct number of floating point registers are not accounted for), which causes the assert error. I will try to make a short demo program that causes this.

And you provided the sample, which I tried to debug without understanding the story.

It was Cypress who needed to use the sample to debug their "code"

and there was no point I should join in.

So I'm very sorry about that.

> On the other hand, the link you mentioned refers to a pretty dated toolchain.

I think the link was for the toolchain "currently" being used with the PSoC Creator.

> Perhaps an update there could resolve the issue as well?

At first I was thinking that it was gdb bug, so I was hoping that updating to a newer version should take care of it.

But since it is the way Cypress specified the their debugger, I'm afraid that newer GCC/GDB may still have same problem.

If possible using other toolchain, such as MDK or IAR might solve the problem, but I have not tried it with PSoC 6.

moto

0 Likes

I updated to the latest available GCC toolchain (gcc-arm-none-eabi-9-2019-q4-major), which I found at https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-.... When using that toolchain, I was unable to reproduce the issue (while actually slightly reducing somewhat the code- size and the performance, based on the optimize settings).

It might be that the code compiles differently, or perhaps the debugger is now instructed to take these extra registers into account. 

From my perspective, the toolchain update fixed the issue.

Thanks for your attention.

Paul

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Paul-san,

From your explanation I was thinking that it was Cypress code which prevents the floating registers to be accessed.

But according to you, updating the toolchain fixed the problem.

I'm a little puzzled. (Still it might have been that Cypress disabled the floating point register access from the previous toolchain).

Anyway I'm very happy hearing that updating the toolchain fixed the problem.

> From my perspective, the toolchain update fixed the issue.

Yes, congratulations to you!

Best Regards,

1-May-2020

Motoo Tanaka

0 Likes