Msg/ClobberedSP: Difference between revisions

From CPUlator Wiki

< Msg
No edit summary
No edit summary
 
(4 intermediate revisions by the same user not shown)
Line 1: Line 1:
A function should always ensure that the stack pointer is the same at the entry and exit of the function. This message tells you that this didn't happen: the stack pointer was different at the function return than when the function was first called.
A function should always ensure that the stack pointer is the same at the entry and exit of the function. This message tells you that this didn't happen: the stack pointer was different at the function return than when the function was first called.
If you also clobbered ra, see also [[Msg/ClobberedRA]]


=== Examples ===
=== Examples ===
Line 14: Line 16:
      
      
MyFunction:
MyFunction:
     push {r4} // Change SP
     push {r4} // Change SP
     bx lr // SP is different at return
     bx lr // SP is different at return
</syntaxhighlight>
</syntaxhighlight>
==== Nios II ====
==== Nios II ====
Line 27: Line 29:
      
      
Function:
Function:
     subi sp, sp, 4 # Modify SP
     subi sp, sp, 4 # Modify SP
     ret # SP is different at return
     ret # SP is different at return
</syntaxhighlight>
==== MIPS ====
<syntaxhighlight lang="Asm" line highlight="10">
.global _start
_start:
    addiu $sp, $0, 0x1000 # Initialize SP
    jal Function
    nop
    nop
   
Function:
    subu $sp, $sp, 4 # Modify SP
    jr $ra # SP is different at return
</syntaxhighlight>
</syntaxhighlight>


Line 34: Line 49:
* This message is complaining that the stack pointer differs between the start of the function and at the function return. Use breakpoints and make a note of the value of the stack pointer at both the function entry and return. Are they the same?
* This message is complaining that the stack pointer differs between the start of the function and at the function return. Use breakpoints and make a note of the value of the stack pointer at both the function entry and return. Are they the same?
* The most common way to use the stack pointer is to modify it while pushing and popping values on the stack. When pushes and pops are mismatched, there is a net change in the stack pointer in the function.
* The most common way to use the stack pointer is to modify it while pushing and popping values on the stack. When pushes and pops are mismatched, there is a net change in the stack pointer in the function.
* The two places where stack pointer manipulations often occur are at the function prologue and epilogue, and allocating and deallocating arguments passed on the stack when calling a function. These operations are all matched. If your function modifies the stack pointer for other purposes, change your code so that this doesn't happen (e.g., copy the stack pointer to another register and modify that, instead of modifying the stack pointer).


=== Implementation ===
=== Implementation ===

Latest revision as of 03:55, 17 March 2019

A function should always ensure that the stack pointer is the same at the entry and exit of the function. This message tells you that this didn't happen: the stack pointer was different at the function return than when the function was first called.

If you also clobbered ra, see also Msg/ClobberedRA

Examples

ARMv7

.global _start
_start:
    mov sp, #0x1000		// Initialize SP to something sane
    bl MyFunction
    nop
    nop
    # ...
    
MyFunction:
    push {r4}				// Change SP
    bx lr					// SP is different at return

Nios II

.global _start
_start:
    movi sp, 0x1000		# Initialize SP
    call Function
    nop
    nop
    
Function:
    subi sp, sp, 4			# Modify SP
    ret					# SP is different at return

MIPS

.global _start
_start:
    addiu $sp, $0, 0x1000		# Initialize SP
    jal Function
    nop
    nop
    
Function:
    subu $sp, $sp, 4			# Modify SP
    jr $ra						# SP is different at return

Debugging

  • This message is complaining that the stack pointer differs between the start of the function and at the function return. Use breakpoints and make a note of the value of the stack pointer at both the function entry and return. Are they the same?
  • The most common way to use the stack pointer is to modify it while pushing and popping values on the stack. When pushes and pops are mismatched, there is a net change in the stack pointer in the function.
  • The two places where stack pointer manipulations often occur are at the function prologue and epilogue, and allocating and deallocating arguments passed on the stack when calling a function. These operations are all matched. If your function modifies the stack pointer for other purposes, change your code so that this doesn't happen (e.g., copy the stack pointer to another register and modify that, instead of modifying the stack pointer).

Implementation

The simulator identifies idiomatic call and return instructions executed at runtime. It records the values of registers when executing call instructions, and verifies that they haven't changed when executing the matching function return. This warning is generated at the return instruction.

Disabling this message

This debugging check can be disabled in the Debugging Checks section of the Settings box: Function clobbered ra or sp.

ARMv7: Function clobbered sp, or bad return