Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mbed_mem_trace.cpp Source File

mbed_mem_trace.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2016 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include <stdlib.h>
00018 #include <stdarg.h>
00019 #include <stdio.h>
00020 #include "platform/mbed_mem_trace.h"
00021 #include "platform/mbed_critical.h"
00022 #include "platform/SingletonPtr.h"
00023 #include "platform/PlatformMutex.h"
00024 
00025 /******************************************************************************
00026  * Internal variables, functions and helpers
00027  *****************************************************************************/
00028 
00029 /* The callback function that will be called after a traced memory operations finishes. */
00030 static mbed_mem_trace_cb_t mem_trace_cb;
00031 /* 'trace_lock_count' guards "trace inside trace" situations (for example, the implementation
00032  * of realloc() might call malloc() internally, and since malloc() is also traced, this could
00033  * result in two calls to the callback function instead of one. */
00034 static uint8_t trace_lock_count;
00035 static SingletonPtr<PlatformMutex>  mem_trace_mutex;
00036 
00037 #define TRACE_FIRST_LOCK() (trace_lock_count < 2)
00038 
00039 
00040 /******************************************************************************
00041  * Public interface
00042  *****************************************************************************/
00043 
00044 void mbed_mem_trace_set_callback(mbed_mem_trace_cb_t cb) {
00045     mem_trace_cb = cb;
00046 }
00047 
00048 void mbed_mem_trace_lock()
00049 {
00050     mem_trace_mutex->lock();
00051     trace_lock_count++;
00052 }
00053 
00054 void mbed_mem_trace_unlock()
00055 {
00056     trace_lock_count--;
00057     mem_trace_mutex->unlock();
00058 }
00059 
00060 void *mbed_mem_trace_malloc(void *res, size_t size, void *caller) {
00061     if (mem_trace_cb) {
00062         if (TRACE_FIRST_LOCK()) {
00063             mem_trace_cb(MBED_MEM_TRACE_MALLOC, res, caller, size);
00064         }
00065     }
00066     return res;
00067 }
00068 
00069 void *mbed_mem_trace_realloc(void *res, void *ptr, size_t size, void *caller) {
00070     if (mem_trace_cb) {
00071         if (TRACE_FIRST_LOCK()) {
00072             mem_trace_cb(MBED_MEM_TRACE_REALLOC, res, caller, ptr, size);
00073         }
00074     }
00075     return res;
00076 }
00077 
00078 void *mbed_mem_trace_calloc(void *res, size_t num, size_t size, void *caller) {
00079     if (mem_trace_cb) {
00080         if (TRACE_FIRST_LOCK()) {
00081             mem_trace_cb(MBED_MEM_TRACE_CALLOC, res, caller, num, size);
00082         }
00083     }
00084     return res;
00085 }
00086 
00087 void mbed_mem_trace_free(void *ptr, void *caller) {
00088     if (mem_trace_cb) {
00089         if (TRACE_FIRST_LOCK()) {
00090             mem_trace_cb(MBED_MEM_TRACE_FREE, NULL, caller, ptr);
00091         }
00092     }
00093 }
00094 
00095 void mbed_mem_trace_default_callback(uint8_t op, void *res, void *caller, ...) {
00096     va_list va;
00097     size_t temp_s1, temp_s2;
00098     void *temp_ptr;
00099 
00100     va_start(va, caller);
00101     switch(op) {
00102         case MBED_MEM_TRACE_MALLOC:
00103             temp_s1 = va_arg(va, size_t);
00104             printf(MBED_MEM_DEFAULT_TRACER_PREFIX "m:%p;%p-%u\n", res, caller, temp_s1);
00105             break;
00106 
00107         case MBED_MEM_TRACE_REALLOC:
00108             temp_ptr = va_arg(va, void*);
00109             temp_s1 = va_arg(va, size_t);
00110             printf(MBED_MEM_DEFAULT_TRACER_PREFIX "r:%p;%p-%p;%u\n", res, caller, temp_ptr, temp_s1);
00111             break;
00112 
00113         case MBED_MEM_TRACE_CALLOC:
00114             temp_s1 = va_arg(va, size_t);
00115             temp_s2 = va_arg(va, size_t);
00116             printf(MBED_MEM_DEFAULT_TRACER_PREFIX "c:%p;%p-%u;%u\n", res, caller, temp_s1, temp_s2);
00117             break;
00118 
00119         case MBED_MEM_TRACE_FREE:
00120             temp_ptr = va_arg(va, void*);
00121             printf(MBED_MEM_DEFAULT_TRACER_PREFIX "f:%p;%p-%p\n", res, caller, temp_ptr);
00122             break;
00123 
00124         default:
00125             printf("?\n");
00126     }
00127     va_end(va);
00128 }
00129