Skip to content

Commit

Permalink
feat(system): add exception handler for load store exception
Browse files Browse the repository at this point in the history
internal gitlab: a3b74e9c
  • Loading branch information
wujiangang committed Jun 26, 2018
1 parent 67bdd07 commit c766134
Show file tree
Hide file tree
Showing 19 changed files with 62 additions and 36 deletions.
30 changes: 15 additions & 15 deletions VERSION
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
gwen:
at : 754dddb
crypto : 350448e
espnow : 350448e
json : ce90efd
main : 754dddb
net80211 : 350448e
pp : 097de86
smartconfig : 350448e
ssl : b19a6f7
upgrade : 5287040
wpa : 350448e
wpa2 : 350448e
wps : 350448e
at : bc85feb
crypto : bc85feb
espnow : bc85feb
json : bc85feb
main : bc85feb
net80211 : bc85feb
pp : bc85feb
smartconfig : bc85feb
ssl : bc85feb
upgrade : bc85feb
wpa : bc85feb
wpa2 : bc85feb
wps : bc85feb

phy:
phy : 1136

gitlab:
driver : 68fc7b06
lwip : c097d4cf
mbedtls : e4dace14
lwip : 3c7a0dbe
mbedtls : 3c7a0dbe
21 changes: 14 additions & 7 deletions include/mem.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,19 @@ bool ICACHE_FLASH_ATTR check_memleak_debug_enable(void)
}
*/

void *pvPortMalloc (size_t sz, const char *, unsigned);
void *pvPortMalloc (size_t sz, const char *, unsigned, bool);
void vPortFree (void *p, const char *, unsigned);
void *pvPortZalloc (size_t sz, const char *, unsigned);
void *pvPortRealloc (void *p, size_t n, const char *, unsigned);

#ifndef MEMLEAK_DEBUG
#define MEMLEAK_DEBUG_ENABLE 0
#define os_free(s) vPortFree(s, "", 0)
#define os_malloc(s) pvPortMalloc(s, "", 0)
#define os_calloc(l, s) pvPortCalloc(l, s, "", 0);
#define os_realloc(p, s) pvPortRealloc(p, s, "", 0)
#define os_zalloc(s) pvPortZalloc(s, "", 0)
#define os_free(s) vPortFree(s, "", __LINE__)
#define os_malloc(s) pvPortMalloc(s, "", __LINE__,true)
#define os_malloc_dram(s) pvPortMalloc(s, "", __LINE__,false)
#define os_calloc(l, s) ({void* ptr = (void*)os_malloc((l) * (s));if(ptr){os_memset(ptr,0x0,(l) * (s));} ptr;})// pvPortCalloc(l, s, "", __LINE__)
#define os_realloc(p, s) pvPortRealloc(p, s, "", __LINE__)
#define os_zalloc(s) os_calloc(1, s)// pvPortZalloc(s, "", __LINE__)
#else
#define MEMLEAK_DEBUG_ENABLE 1

Expand All @@ -61,9 +62,15 @@ do{\
#define os_malloc(s) \
({ \
static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; \
pvPortMalloc(s, mem_debug_file, __LINE__); \
pvPortMalloc(s, mem_debug_file, __LINE__,true); \
})

#define os_malloc_dram(s) \
({ \
static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; \
pvPortMalloc(s, mem_debug_file, __LINE__,false); \
})

#define os_calloc(l, s) \
({ \
static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; \
Expand Down
Binary file modified lib/libat.a
Binary file not shown.
Binary file modified lib/libcrypto.a
Binary file not shown.
Binary file modified lib/libespnow.a
Binary file not shown.
Binary file modified lib/libjson.a
Binary file not shown.
Binary file modified lib/liblwip.a
Binary file not shown.
Binary file modified lib/libmain.a
Binary file not shown.
Binary file modified lib/libmbedtls.a
Binary file not shown.
Binary file modified lib/libnet80211.a
Binary file not shown.
Binary file modified lib/libpp.a
Binary file not shown.
Binary file modified lib/libsmartconfig.a
Binary file not shown.
Binary file modified lib/libssl.a
Binary file not shown.
Binary file modified lib/libupgrade.a
Binary file not shown.
Binary file modified lib/libwpa.a
Binary file not shown.
Binary file modified lib/libwpa2.a
Binary file not shown.
Binary file modified lib/libwps.a
Binary file not shown.
19 changes: 12 additions & 7 deletions third_party/include/lwip/mem.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,19 @@ typedef size_t mem_size_t;
*/
#ifndef MEMLEAK_DEBUG
#ifndef mem_free
#define mem_free vPortFree
#define mem_free(s) vPortFree(s, "", __LINE__)
#endif
#ifndef mem_malloc
#define mem_malloc pvPortMalloc
#define mem_malloc(s) pvPortMalloc(s, "", __LINE__,false)
#endif
#ifndef mem_calloc
#define mem_calloc pvPortCalloc
#define mem_calloc(l, s) ({void* ptr = (void*)pvPortMalloc((l) * (s), "", __LINE__,true);if(ptr){os_memset(ptr,0x0,(l) * (s));} ptr;})// pvPortCalloc(l, s, "", __LINE__)
#endif
#ifndef mem_realloc
#define mem_realloc pvPortRealloc
#define mem_realloc(p, s) pvPortRealloc(p, s, "", __LINE__)
#endif
#ifndef mem_zalloc
#define mem_zalloc pvPortZalloc
#define mem_zalloc(s) mem_calloc(1,s) // pvPortZalloc(s, "", __LINE__)
#endif
#else
#ifndef mem_free
Expand All @@ -74,8 +74,9 @@ do{\
vPortFree(s, file, __LINE__);\
}while(0)
#endif

#ifndef mem_malloc
#define mem_malloc(s) ({const char *file = mem_debug_file; pvPortMalloc(s, file, __LINE__);})
#define mem_malloc(s) (const char *file = mem_debug_file; pvPortMalloc(s, file, __LINE__,false);})
#endif
#ifndef mem_calloc
#define mem_calloc(l, s) ({const char *file = mem_debug_file; pvPortCalloc(l, s, file, __LINE__);})
Expand All @@ -90,7 +91,11 @@ do{\
#endif

#ifndef os_malloc
#define os_malloc(s) mem_malloc((s))
#ifndef MEMLEAK_DEBUG
#define os_malloc(s) pvPortMalloc(s, "", __LINE__,true)
#else
#define os_malloc(s) ({const char *file = mem_debug_file; pvPortMalloc(s, file, __LINE__,true);})
#endif
#endif
#ifndef os_realloc
#define os_realloc(p, s) mem_realloc((p), (s))
Expand Down
28 changes: 21 additions & 7 deletions third_party/include/mbedtls/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,17 @@
extern "C" {
#endif

#include "osapi.h"
/**
* \name SECTION: Module settings
*
* The configuration options you can set for this module are in this section.
* Either change them in config.h or define them on the compiler command line.
* \{
*/
extern int ets_snprintf(char *buf, unsigned int size, const char *format, ...);
extern void *pvPortCalloc(unsigned int count, unsigned int size);
extern void vPortFree( void *pv );
// extern int ets_snprintf(char *buf, unsigned int size, const char *format, ...);
void *pvPortCalloc(unsigned int count, unsigned int size, const char*, unsigned);
void vPortFree (void *p, const char *, unsigned);
#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
#include <stdio.h>
Expand All @@ -61,10 +62,18 @@ extern void vPortFree( void *pv );
#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use */
#endif
#if !defined(MBEDTLS_PLATFORM_STD_CALLOC)
#define MBEDTLS_PLATFORM_STD_CALLOC pvPortCalloc /**< Default allocator to use */
#ifndef MEMLEAK_DEBUG
#define MBEDTLS_PLATFORM_STD_CALLOC(l, s) ({void* p = pvPortMalloc((l) * (s), "", __LINE__,true);if(p){os_memset(p,0x0,(l) * (s));} p;})// pvPortCalloc(l, s, "", __LINE__) // pvPortCalloc /**< Default allocator to use */
#else
#define MBEDTLS_PLATFORM_STD_CALLOC(l, s) ({const char *file = mem_debug_file;void* p = pvPortMalloc((l) * (s), file, __LINE__,true);if(p){os_memset(p,0x0,(l) * (s));} p;})// ({const char *file = mem_debug_file; pvPortCalloc(l, s, file, __LINE__);})
#endif
#endif
#if !defined(MBEDTLS_PLATFORM_STD_FREE)
#define MBEDTLS_PLATFORM_STD_FREE vPortFree /**< Default free to use */
#ifndef MEMLEAK_DEBUG
#define MBEDTLS_PLATFORM_STD_FREE(s) vPortFree(s, "", __LINE__) // vPortFree /**< Default free to use */
#else
#define MBEDTLS_PLATFORM_STD_FREE(s) do{const char *file = mem_debug_file;vPortFree(s, file, __LINE__);}while(0)
#endif
#endif
#if !defined(MBEDTLS_PLATFORM_STD_EXIT)
#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default free to use */
Expand Down Expand Up @@ -103,8 +112,13 @@ int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
void (*free_func)( void * ) );
#endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */
#else /* !MBEDTLS_PLATFORM_MEMORY */
#define mbedtls_free vPortFree
#define mbedtls_calloc pvPortCalloc
#ifndef MEMLEAK_DEBUG
#define mbedtls_free(s) vPortFree(s, "", __LINE__)
#define mbedtls_calloc(l, s) ({void* p = (void*)pvPortMalloc((l) * (s), "", __LINE__,true);if(p){os_memset(p,0x0,(l) * (s));} p;})// pvPortCalloc(l, s, "", __LINE__)
#else
#define mbedtls_free(s) do{const char *file = mem_debug_file;vPortFree(s, file, __LINE__);}while(0)
#define mbedtls_calloc(l, s) ({const char *file = mem_debug_file; pvPortCalloc(l, s, file, __LINE__);})
#endif
#endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */

/*
Expand Down

13 comments on commit c766134

@ataweg
Copy link

@ataweg ataweg commented on c766134 Jun 29, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with this fix I got much more free heap than before.
At system startup the free heap size reported with system_get_free_heap_size() grows from 38912 to 74160 byte. What has happend? Where does the additional free memory come from? Or is that fake?

Viele Gruesse
Axel

@kriegste
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will SSL connections benefit from the increased heap? This has been the bottleneck in the past versions.

@xcguang
Copy link
Collaborator

@xcguang xcguang commented on c766134 Jul 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi,
We do some optimization about malloc, and got some iram space as memory.

@xcguang
Copy link
Collaborator

@xcguang xcguang commented on c766134 Jul 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kriegste Yes, it can work for SSL conenctions and WPA2 enterprise.
We modified the action of os_malloc, and the os_malloc_dram is the same as os_malloc in the old version, the os_malloc is allocated from iram, which is added in the commit.

@valkuc
Copy link

@valkuc valkuc commented on c766134 Jul 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please explain difference between os_malloc and os_malloc_dram and when each of them can used? Will this change be reflected in NON OS SDK document?

@xcguang
Copy link
Collaborator

@xcguang xcguang commented on c766134 Jul 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @valkuc
Now os_malloc allocates memory from iram, and os_malloc_dram allocates memory from dram.
If you operate memory that is not four byte aligned, which is allocated by os_malloc, an exception will be generated, and we do something in the exception handler to read/write the correct data, then restore from exception. So os_malloc_dram is more efficient than os_malloc. In most instances, os_malloc works good but in Wi-Fi interrupt, which operation is in the liblwip.a and libpp.a.
By default, in order to keep efficient, os_malloc_dram is used in the library, and os_malloc is for the user. If you need efficient code, you can also use os_malloc_dram instead of os_malloc.

@valkuc
Copy link

@valkuc valkuc commented on c766134 Jul 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am I correctly understand that previously os_malloc allocated memory from DRAM and now to make our code compatible with this change we need to replace all occurrences of os_malloc with os_malloc_dram?

@xcguang
Copy link
Collaborator

@xcguang xcguang commented on c766134 Jul 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, if the dram is enough for you, you can replace it, even though you don't do it, it should work well.
And if you need more memory, like creating more ssl connections, you'd better using os_malloc.
It will be allocated from dram automatically, if malloc memory fail from iram. But if you use os_malloc_dram to malloc, it will fail when dram is insufficient, and it doesn't be allocated from iram automatically.

@valkuc
Copy link

@valkuc valkuc commented on c766134 Jul 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, now all clear. It will be good if this will be documented somewhere.

@xcguang
Copy link
Collaborator

@xcguang xcguang commented on c766134 Jul 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your advice, we will add it ASAP.

@ataweg
Copy link

@ataweg ataweg commented on c766134 Jul 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the new exception handler compatible with the gdbstup? I have seen some SIGSEGV debugging with gdb and gdbstub that make me doubt it.
Please make debugging with gdb and gdbstub work again.
Viele Gruesse
Axel

@xcguang
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ataweg Sorry, it is for load/store data in iram.

@ataweg
Copy link

@ataweg ataweg commented on c766134 Jul 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's exactly what I'm watching. If an unaligned value or 8/16 bit value is written or read to/from the iram, gdb reports a SIGSEGV.

Program received signal SIGSEGV, Segmentation fault.
0x40247593 in single_key_init (gpio_id=gpio_id@entry=0x0, gpio_name=gpio_name@entry=0x60000834, gpio_func=gpio_func@entry=0x0,
    very_long_press=very_long_press@entry=0x402465d4 <buttonVeryLongPress>, press_very_long_time=press_very_long_time@entry=0x2710,
    long_press=long_press@entry=0x4024659c <buttonLongPress>, press_long_time=press_long_time@entry=0x7d0,
    short_press=short_press@entry=0x4024661c <buttonShortPress>) at modules/keys.c:96
96         single_key->key_state   = KEY_IDLE;
(gdb) disass single_key_init
Dump of assembler code for function single_key_init:
   0x40247540 <+0>:     addi    a1, a1, -48
   0x40247543 <+3>:     s32i    a0, a1, 44
   0x40247546 <+6>:     s32i    a12, a1, 40
   0x40247549 <+9>:     s32i.n  a13, a1, 36
   0x4024754b <+11>:    s32i.n  a14, a1, 32
   0x4024754d <+13>:    s32i.n  a15, a1, 28
   0x4024754f <+15>:    mov.n   a13, a3
   0x40247551 <+17>:    s32i.n  a5, a1, 0
   0x40247553 <+19>:    s32i.n  a6, a1, 4
   0x40247555 <+21>:    s32i.n  a7, a1, 8
   0x40247557 <+23>:    extui   a15, a2, 0, 8
   0x4024755a <+26>:    extui   a14, a4, 0, 8
   0x4024755d <+29>:    l32r    a0, 0x4023834c
   0x40247560 <+32>:    callx0  a0
   0x40247563 <+35>:    movi    a3, 0x3e8
   0x40247566 <+38>:    l32r    a0, 0x40213710
   0x40247569 <+41>:    callx0  a0
   0x4024756c <+44>:    call0   0x40242a44 <sys_time2str>
   0x4024756f <+47>:    movi.n  a5, 92
   0x40247571 <+49>:    l32r    a4, 0x40247378
   0x40247574 <+52>:    or      a3, a2, a2
   0x40247577 <+55>:    l32r    a2, 0x40247530
   0x4024757a <+58>:    l32r    a0, 0x402132c4
   0x4024757d <+61>:    callx0  a0
   0x40247580 <+64>:    movi.n  a5, 1
   0x40247582 <+66>:    movi.n  a4, 94
   0x40247584 <+68>:    l32r    a3, 0x40247534
   0x40247587 <+71>:    movi.n  a2, 52
   0x40247589 <+73>:    l32r    a0, 0x4024753c
   0x4024758c <+76>:    callx0  a0
   0x4024758f <+79>:    mov.n   a12, a2
   0x40247591 <+81>:    movi.n  a2, 0
=> 0x40247593 <+83>:    s8i     a2, a12, 0
   0x40247596 <+86>:    s8i     a2, a12, 1
   0x40247599 <+89>:    s8i     a15, a12, 2
   0x4024759c <+92>:    s8i     a14, a12, 3
   0x4024759f <+95>:    s32i.n  a13, a12, 4
   0x402475a1 <+97>:    movi.n  a2, 0
   0x402475a3 <+99>:    s32i.n  a2, a12, 8
   0x402475a5 <+101>:   l32i.n  a2, a1, 52
   0x402475a7 <+103>:   s32i.n  a2, a12, 12
   0x402475a9 <+105>:   l32i.n  a2, a1, 8
   0x402475ab <+107>:   s32i.n  a2, a12, 16
   0x402475ad <+109>:   l32i.n  a2, a1, 48

Please sign in to comment.