aboutsummaryrefslogtreecommitdiff
path: root/py/qstr.c
diff options
context:
space:
mode:
authorColin Hogben <colin@infinnovation.co.uk>2016-10-31 14:05:56 +0000
committerDamien George <damien.p.george@gmail.com>2016-11-02 23:15:41 +1100
commitf9b6b37cf65c4f65c4ad461d439fbf624c0f10c1 (patch)
tree7f80da83630a8e43d0c9cf9522b4125eaa6d2ff9 /py/qstr.c
parente5f06559e6762b00e36a66901ba092676cd8e019 (diff)
py: Fix wrong assumption that m_renew will not move if shrinking
In both parse.c and qstr.c, an internal chunking allocator tidies up by calling m_renew to shrink an allocated chunk to the size used, and assumes that the chunk will not move. However, when MICROPY_ENABLE_GC is false, m_renew calls the system realloc, which does not guarantee this behaviour. Environments where realloc may return a different pointer include: (1) mbed-os with MBED_HEAP_STATS_ENABLED (which adds a wrapper around malloc & friends; this is where I was hit by the bug); (2) valgrind on linux (how I diagnosed it). The fix is to call m_renew_maybe with allow_move=false.
Diffstat (limited to 'py/qstr.c')
-rw-r--r--py/qstr.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/py/qstr.c b/py/qstr.c
index 28df06ca3..5aa161064 100644
--- a/py/qstr.c
+++ b/py/qstr.c
@@ -199,7 +199,7 @@ qstr qstr_from_strn(const char *str, size_t len) {
byte *new_p = m_renew_maybe(byte, MP_STATE_VM(qstr_last_chunk), MP_STATE_VM(qstr_last_alloc), MP_STATE_VM(qstr_last_alloc) + n_bytes, false);
if (new_p == NULL) {
// could not grow existing memory; shrink it to fit previous
- (void)m_renew(byte, MP_STATE_VM(qstr_last_chunk), MP_STATE_VM(qstr_last_alloc), MP_STATE_VM(qstr_last_used));
+ (void)m_renew_maybe(byte, MP_STATE_VM(qstr_last_chunk), MP_STATE_VM(qstr_last_alloc), MP_STATE_VM(qstr_last_used), false);
MP_STATE_VM(qstr_last_chunk) = NULL;
} else {
// could grow existing memory