Skip to content

assert(0) doesnt cause trap without GDB and breaks execution path #4480

Closed
@romansavrulin

Description

@romansavrulin

Basic Infos

  • This issue complies with the issue POLICY doc.
  • I have read the documentation at readthedocs and the issue is not addressed there.
  • I have tested that the issue is present in current master branch (aka latest git).
  • I have searched the issue tracker for a similar issue.
  • If there is a stack dump, I have decoded it.
  • I have filled out all fields below.

Platform

  • Hardware: [ESP-12]
  • Core Version: [2.4.0]
  • Development Env: [Arduino IDE]
  • Operating System: [Windows]

Settings in IDE

  • Module: [Nodemcu]

Problem Description

assert(0) doesn't cause neither trap, nor backtrace, all instructions after that call gets optimized-out, breaking execution logic.

Because assert(0) returns, MCU continues code execution with broken logic and can cause fault later on, that is very hard to catch.

MCVE Sketch

#include <ESP8266WiFi.h>
#include "assert.h"
/*********************** Global vars ***********************/
char *buffer;
const char *watermark = "ZZZZ";
char *wmBuffer = NULL;
unsigned int capacity;
/*********************** Global vars ***********************/

unsigned char changeBuffer(unsigned int maxStrLen);


void setup() {
    Serial.begin(115200);
    Serial.setDebugOutput(true);
}

void loop() {
    delay(400);

    changeBuffer(14);       //random value
}



unsigned char changeBuffer(unsigned int maxStrLen){
    auto watermarkLen = strlen(watermark);

    size_t newSize = (uint32_t)(maxStrLen + 16 + watermarkLen * 2 + 2) & (~0xf);
    int s = newSize;
    ets_printf("\nnew size %d  || ", newSize);

    char *newbuffer = (char *) realloc(wmBuffer, newSize);

    if (!newbuffer) {
        ets_printf("gotcha! %d %d\n", newSize, watermarkLen);
        return 0;
    }

    if(newbuffer) {
        assert(0); //<-- expected to trap
        size_t oldSize = capacity + 1; // include NULL.
    wmBuffer = newbuffer;

    memcpy(newbuffer + newSize - watermarkLen,  watermark, strlen(watermark));

        capacity = newSize - 1 - watermarkLen;

        ets_printf(" 1 ");
        ets_printf(" 2 ");
        buffer = newbuffer + watermarkLen;
        ets_printf(" 3 ");
        //assert(0);

        ets_printf("leaving one");
        return 1;
    }
    ets_printf("leaving zero");
    return 0; 
}

Debug Messages

Debug messages go here

$ xtensa-lx106-elf-objdump.exe -d bug_catcher.ino.elf | sed '/<_Z12changeBufferj>:/,/^$/!d'

40202098 <_Z12changeBufferj>:
40202098:       f0c112          addi    a1, a1, -16
4020209b:       21c9            s32i.n  a12, a1, 8
4020209d:       02cd            mov.n   a12, a2
4020209f:       fff721          l32r    a2, 4020207c <setup+0x2c>
402020a2:       3109            s32i.n  a0, a1, 12
402020a4:       0228            l32i.n  a2, a2, 0
402020a6:       11d9            s32i.n  a13, a1, 4
402020a8:       01e9            s32i.n  a14, a1, 0
402020aa:       12ccc2          addi    a12, a12, 18
402020ad:       01de85          call0   40203e98 <strlen>
402020b0:       90c2c0          addx2   a12, a2, a12
402020b3:       02ed            mov.n   a14, a2
402020b5:       027c            movi.n  a2, -16
402020b7:       10cc20          and     a12, a12, a2
402020ba:       fff121          l32r    a2, 40202080 <setup+0x30>
402020bd:       0c3d            mov.n   a3, a12
402020bf:       fc1801          l32r    a0, 40201120 <ets_puts_P+0xac>
402020c2:       0000c0          callx0  a0
402020c5:       ffef21          l32r    a2, 40202084 <setup+0x34>
402020c8:       0c3d            mov.n   a3, a12
402020ca:       0228            l32i.n  a2, a2, 0
402020cc:       ff6f01          l32r    a0, 40201e88 <_free_r+0x14>
402020cf:       0000c0          callx0  a0
402020d2:       02dd            mov.n   a13, a2
402020d4:       c28c            beqz.n  a2, 402020e4 <_Z12changeBufferj+0x4c>
402020d6:       ffed21          l32r    a2, 4020208c <setup+0x3c>
402020d9:       ffed41          l32r    a4, 40202090 <setup+0x40>
402020dc:       ffee51          l32r    a5, 40202094 <setup+0x44>
402020df:       932c            movi.n  a3, 41
402020e1:       ff1b85          call0   4020129c <__assert_func>   

/// <-- no if(newbuffer) branch at all after that, but assert returns and we get unexpected logic.

402020e4:       ffe921          l32r    a2, 40202088 <setup+0x38>
402020e7:       0c3d            mov.n   a3, a12
402020e9:       0e4d            mov.n   a4, a14
402020eb:       fc0d01          l32r    a0, 40201120 <ets_puts_P+0xac>
402020ee:       0000c0          callx0  a0
402020f1:       3108            l32i.n  a0, a1, 12
402020f3:       0d2d            mov.n   a2, a13
402020f5:       21c8            l32i.n  a12, a1, 8
402020f7:       11d8            l32i.n  a13, a1, 4
402020f9:       01e8            l32i.n  a14, a1, 0
402020fb:       10c112          addi    a1, a1, 16
402020fe:       f00d            ret.n

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions