1 /*
2  * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3  */
4 
5 #include "linkkit/infra/infra_config.h"
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <stdint.h>
11 #include <stdarg.h>
12 
13 #include "linkkit/infra/infra_mem_stats.h"
14 #ifdef INFRA_LOG
15 #include "linkkit/infra/infra_log.h"
16 #define utils_emerg(...)   log_emerg("util", __VA_ARGS__)
17 #define utils_crit(...)    log_crit("util", __VA_ARGS__)
18 #define utils_err(...)     log_err("util", __VA_ARGS__)
19 #define utils_warning(...) log_warning("util", __VA_ARGS__)
20 #define utils_info(...)    log_info("util", __VA_ARGS__)
21 #define utils_debug(...)   log_debug("util", __VA_ARGS__)
22 #else
23 #define utils_emerg(...)
24 #define utils_crit(...)
25 #define utils_err(...)
26 #define utils_warning(...)
27 #define utils_info(...)
28 #define utils_debug(...)
29 #endif
30 
31 #ifdef INFRA_MEM_STATS
32 
33 LIST_HEAD(mem_recs);
34 LIST_HEAD(mem_module_statis);
35 
36 typedef struct {
37     char *func_name;
38     int line;
39     list_head_t func_head;
40 } calling_stack_t;
41 
42 typedef struct {
43     char module_name[32];
44     calling_stack_t calling_stack;
45     int bytes_total_allocated;
46     int bytes_total_freed;
47     int bytes_total_in_use;
48     int bytes_max_allocated;
49     int bytes_max_in_use;
50     int iterations_allocated;
51     int iterations_freed;
52     int iterations_in_use;
53     int iterations_max_in_use;
54 } mem_statis_t;
55 
56 typedef struct {
57     mem_statis_t mem_statis;
58     list_head_t list;
59 } module_mem_t;
60 
61 /* sort module used */
_mem_cmp_max_used(list_head_t * a,list_head_t * b)62 static int _mem_cmp_max_used(list_head_t *a, list_head_t *b)
63 {
64     module_mem_t *temp_a = list_entry(a, module_mem_t, list);
65     module_mem_t *temp_b = list_entry(b, module_mem_t, list);
66 
67     if (a == NULL || b == NULL) {
68         return 0;
69     }
70 
71     /* return true to swap if a < b */
72     return (temp_a->mem_statis.bytes_max_in_use <
73             temp_b->mem_statis.bytes_max_in_use);
74 }
75 
_mem_swap_module_pos(list_head_t * a,list_head_t * b)76 static void _mem_swap_module_pos(list_head_t *a, list_head_t *b)
77 {
78     list_head_t temp = { NULL, NULL };
79 
80     if (a == NULL || a == NULL) {
81         return;
82     }
83 
84     list_add(&temp, b);
85     list_del(b);
86     list_add(b, a);
87     list_del(a);
88     list_add(a, &temp);
89     list_del(&temp);
90 }
91 
_mem_sort_module_pos(list_head_t * head)92 static void _mem_sort_module_pos(list_head_t *head)
93 {
94     list_head_t *start = NULL;
95     list_head_t *end = NULL;
96 
97     if (head == NULL) {
98         return;
99     }
100 
101     for (end = head->prev; end != head;
102          end = end->prev) { /* list_for_each_prev */
103         list_for_each(start, head)
104         {
105             if (start == end) {
106                 break;
107             }
108 
109             if (_mem_cmp_max_used(start, start->next)) {
110                 _mem_swap_module_pos(start, start->next);
111 
112                 start = start->prev;
113                 if (start == end) {
114                     end = end->next;
115                 }
116             }
117         }
118     }
119 }
120 
121 static void *mutex_mem_stats = NULL;
122 static int bytes_total_allocated;
123 static int bytes_total_freed;
124 static int bytes_total_in_use;
125 static int bytes_max_allocated;
126 static int bytes_max_in_use;
127 static int iterations_allocated;
128 static int iterations_freed;
129 static int iterations_in_use;
130 static int iterations_max_in_use;
131 
132 #if defined(__UBUNTU_SDK_DEMO__)
133 
134 static int tracking_malloc_callstack = 1;
135 
LITE_strdup(const char * src,...)136 char *LITE_strdup(const char *src, ...)
137 {
138     int len = 0;
139     char *dst = NULL;
140 
141     if (!src) {
142         return NULL;
143     }
144     len = strlen(src) + 1;
145     if (len > 1024) {
146         utils_err("Too long string to duplicate, abort! len = %d", len);
147         return NULL;
148     }
149 
150     dst = (char *)HAL_Malloc(sizeof(char) * len);
151 
152     if (!dst) {
153         return NULL;
154     }
155     strncpy(dst, src, len);
156 
157     return dst;
158 }
159 
record_backtrace(int * level,char *** trace)160 static int record_backtrace(int *level, char ***trace)
161 {
162 #define MAX_BT_LEVEL 8
163 
164     void *buffer[MAX_BT_LEVEL];
165 
166     *level = backtrace(buffer, MAX_BT_LEVEL);
167     *trace = backtrace_symbols(buffer, *level);
168     if (*trace == NULL) {
169         utils_err("backtrace_symbols returns NULL!");
170         return -1;
171     }
172 
173     return 0;
174 }
175 
LITE_track_malloc_callstack(int state)176 void LITE_track_malloc_callstack(int state)
177 {
178     tracking_malloc_callstack = state;
179 }
180 
181 #else
LITE_track_malloc_callstack(int state)182 void LITE_track_malloc_callstack(int state)
183 {
184 }
185 
186 #endif /* defined(__UBUNTU_SDK_DEMO__) */
187 
LITE_realloc_internal(const char * f,const int l,void * ptr,int size,...)188 void *LITE_realloc_internal(const char *f, const int l, void *ptr, int size,
189                             ...)
190 {
191     void *temp = NULL;
192     int magic = 0;
193     char *module_name = NULL;
194     va_list ap;
195 
196     if (size <= 0) {
197         return NULL;
198     }
199 
200     va_start(ap, size);
201     magic = va_arg(ap, int);
202     if (MEM_MAGIC == magic) {
203         module_name = va_arg(ap, char *);
204     }
205     va_end(ap);
206 
207     temp = LITE_malloc_internal(f, l, size, magic, module_name);
208 
209     if (NULL == temp) {
210         utils_err("allocate %d bytes from %s(%d) failed", size, f, l);
211         return NULL;
212     }
213 
214     if (ptr) {
215         memcpy(temp, ptr, size);
216 
217         LITE_free(ptr);
218     }
219 
220     return temp;
221 }
222 
_create_mem_table(char * module_name,struct list_head * list_head)223 void *_create_mem_table(char *module_name, struct list_head *list_head)
224 {
225     module_mem_t *pos = NULL;
226     int len = 0;
227 
228     if (!module_name || !list_head) {
229         return NULL;
230     }
231 
232     pos = HAL_Malloc(sizeof(module_mem_t));
233     if (!pos) {
234         return NULL;
235     }
236     memset(pos, 0, sizeof(module_mem_t));
237     len = strlen(module_name);
238     memcpy(pos->mem_statis.module_name, module_name,
239            (len >= sizeof(pos->mem_statis.module_name))
240                ? (sizeof(pos->mem_statis.module_name) - 1)
241                : len);
242 
243     INIT_LIST_HEAD(&pos->mem_statis.calling_stack.func_head);
244 
245     list_add_tail(&pos->list, list_head);
246     return (void *)pos;
247 }
248 
_find_mem_table(char * module_name,struct list_head * list_head)249 void *_find_mem_table(char *module_name, struct list_head *list_head)
250 {
251     module_mem_t *pos = NULL, *tmp = NULL;
252 
253     if (!module_name || !list_head) {
254         return NULL;
255     }
256 
257     list_for_each_entry_safe(pos, tmp, list_head, list, module_mem_t)
258     {
259         if (!strcmp(module_name, pos->mem_statis.module_name)) {
260             return (void *)pos;
261         }
262     }
263 
264     return NULL;
265 }
266 
_del_mem_table(char * module_name,struct list_head * list_head)267 int _del_mem_table(char *module_name, struct list_head *list_head)
268 {
269     int ret = -1;
270 
271     calling_stack_t *calling_stack_pos = NULL, *tmp = NULL;
272     module_mem_t *table_pos =
273         (module_mem_t *)_find_mem_table(module_name, list_head);
274     if (table_pos) {
275         list_for_each_entry_safe(calling_stack_pos, tmp,
276                                  &table_pos->mem_statis.calling_stack.func_head,
277                                  func_head, calling_stack_t)
278         {
279             if (calling_stack_pos) {
280                 list_del(&calling_stack_pos->func_head);
281                 if (calling_stack_pos->func_name) {
282                     HAL_Free(calling_stack_pos->func_name);
283                     calling_stack_pos->func_name = NULL;
284                 }
285                 HAL_Free(calling_stack_pos);
286                 calling_stack_pos = NULL;
287             }
288         }
289 
290         list_del(&table_pos->list);
291         HAL_Free(table_pos);
292         table_pos = NULL;
293         ret = 0;
294     }
295     return ret;
296 }
297 
_count_malloc_internal(const char * f,const int l,OS_malloc_record * os_malloc_pos,va_list ap)298 int _count_malloc_internal(const char *f, const int l,
299                            OS_malloc_record *os_malloc_pos, va_list ap)
300 {
301     int ret = -1;
302 
303     int magic = 0;
304     char is_repeat = 0;
305     char *module_name = NULL;
306     module_mem_t *pos = NULL;
307     calling_stack_t *call_pos, *call_tmp;
308     calling_stack_t *entry = NULL;
309 
310     magic = va_arg(ap, int);
311     if (MEM_MAGIC == magic) {
312         module_name = va_arg(ap, char *);
313     } else {
314         module_name = "unknown";
315     }
316 
317     pos = (module_mem_t *)_find_mem_table(module_name, &mem_module_statis);
318     if (!pos) {
319         pos = (module_mem_t *)_create_mem_table(module_name, &mem_module_statis);
320         if (pos == NULL) {
321             utils_err("create_mem_table:[%s] failed!", module_name);
322             return ret;
323         }
324     }
325     os_malloc_pos->mem_table = (void *)pos;
326 
327     if (!strcmp(pos->mem_statis.module_name, "unknown")) {
328         list_for_each_entry_safe(call_pos, call_tmp,
329                                  &pos->mem_statis.calling_stack.func_head,
330                                  func_head, calling_stack_t)
331         {
332             if (!strcmp(call_pos->func_name, f) && (call_pos->line == l)) {
333                 is_repeat = 1;
334                 break;
335             }
336         }
337         if (!is_repeat) {
338             entry = HAL_Malloc(sizeof(calling_stack_t));
339             if (!entry) {
340                 return ret;
341             }
342 
343             memset(entry, 0, sizeof(calling_stack_t));
344             entry->func_name = LITE_strdup(f);
345             entry->line = l;
346             list_add(&entry->func_head,
347                      &pos->mem_statis.calling_stack.func_head);
348         }
349     }
350 
351     pos->mem_statis.iterations_allocated += 1;
352     pos->mem_statis.bytes_total_allocated += os_malloc_pos->buflen;
353     pos->mem_statis.bytes_total_in_use += os_malloc_pos->buflen;
354     pos->mem_statis.bytes_max_in_use =
355         (pos->mem_statis.bytes_max_in_use > pos->mem_statis.bytes_total_in_use)
356             ? pos->mem_statis.bytes_max_in_use
357             : pos->mem_statis.bytes_total_in_use;
358     pos->mem_statis.bytes_max_allocated =
359         (pos->mem_statis.bytes_max_allocated >= os_malloc_pos->buflen)
360             ? pos->mem_statis.bytes_max_allocated
361             : os_malloc_pos->buflen;
362 
363     pos->mem_statis.iterations_in_use += 1;
364     pos->mem_statis.iterations_max_in_use =
365         (pos->mem_statis.iterations_in_use >
366          pos->mem_statis.iterations_max_in_use)
367             ? pos->mem_statis.iterations_in_use
368             : pos->mem_statis.iterations_max_in_use;
369     ret = 0;
370 
371     return ret;
372 }
373 
_count_free_internal(void * ptr,OS_malloc_record * os_malloc_pos)374 void _count_free_internal(void *ptr, OS_malloc_record *os_malloc_pos)
375 {
376     module_mem_t *pos = NULL;
377 
378     pos = (module_mem_t *)(os_malloc_pos->mem_table);
379     if (!pos) {
380         utils_err("find mem_table faild");
381         return;
382     }
383 
384     pos->mem_statis.iterations_freed += 1;
385     pos->mem_statis.iterations_in_use -= 1;
386 
387     pos->mem_statis.bytes_total_freed += os_malloc_pos->buflen;
388     pos->mem_statis.bytes_total_in_use -= os_malloc_pos->buflen;
389 }
390 
LITE_malloc_internal(const char * f,const int l,int size,...)391 void *LITE_malloc_internal(const char *f, const int l, int size, ...)
392 {
393     void *ptr = NULL;
394     OS_malloc_record *pos;
395 
396     if (size <= 0) {
397         return NULL;
398     }
399 
400     ptr = HAL_Malloc(size);
401     if (!ptr) {
402         return NULL;
403     }
404 
405     if (mutex_mem_stats == NULL) {
406         mutex_mem_stats = HAL_MutexCreate();
407     }
408     HAL_MutexLock(mutex_mem_stats);
409 
410     iterations_allocated += 1;
411     bytes_total_allocated += size;
412     bytes_total_in_use += size;
413     bytes_max_in_use = (bytes_max_in_use > bytes_total_in_use)
414                            ? bytes_max_in_use
415                            : bytes_total_in_use;
416     bytes_max_allocated =
417         (bytes_max_allocated >= size) ? bytes_max_allocated : size;
418 
419 #if defined(WITH_TOTAL_COST_WARNING)
420     if (bytes_total_in_use > WITH_TOTAL_COST_WARNING) {
421         utils_debug(" ");
422         utils_debug("==== PRETTY HIGH TOTAL IN USE: %d BYTES ====",
423                     bytes_total_in_use);
424         LITE_dump_malloc_free_stats(LOG_DEBUG_LEVEL);
425     }
426 #endif
427 
428     iterations_in_use += 1;
429     iterations_max_in_use = (iterations_in_use > iterations_max_in_use)
430                                 ? iterations_in_use
431                                 : iterations_max_in_use;
432 
433     pos = HAL_Malloc(sizeof(OS_malloc_record));
434     if (NULL == pos) {
435         HAL_Free(ptr);
436         HAL_MutexUnlock(mutex_mem_stats);
437         return NULL;
438     }
439     memset(pos, 0, sizeof(OS_malloc_record));
440 
441     pos->buf = ptr;
442     pos->buflen = size;
443     pos->func = (char *)f;
444     pos->line = (int)l;
445 #if defined(__UBUNTU_SDK_DEMO__)
446     if (tracking_malloc_callstack) {
447         record_backtrace(&pos->bt_level, &pos->bt_symbols);
448     }
449 #endif
450 
451     list_add_tail(&pos->list, &mem_recs);
452 
453     {
454         va_list ap;
455         va_start(ap, size);
456         _count_malloc_internal(f, l, pos, ap);
457         va_end(ap);
458     }
459 
460 #if defined(WITH_ALLOC_WARNING_THRESHOLD)
461     if (size > WITH_ALLOC_WARNING_THRESHOLD) {
462         int k;
463 
464         log_warning("utils", "large allocating @ %s(%d) for %04d bytes!", f, l,
465                     size);
466         LITE_printf("\r\n");
467 #if defined(__UBUNTU_SDK_DEMO__)
468         for (k = 0; k < pos->bt_level; ++k) {
469             int m;
470             const char *p = strchr(pos->bt_symbols[k], '(');
471 
472             if (p[1] == ')') {
473                 continue;
474             }
475             for (m = 0; m < k; ++m) {
476                 LITE_printf("  ");
477             }
478 
479             LITE_printf("%s\r\n", p);
480         }
481 #endif
482         LITE_printf("\r\n");
483     }
484 #endif
485     memset(ptr, 0, size);
486     HAL_MutexUnlock(mutex_mem_stats);
487     return ptr;
488 }
489 
LITE_free_internal(void * ptr)490 void LITE_free_internal(void *ptr)
491 {
492     OS_malloc_record *pos;
493     OS_malloc_record *next;
494     int found = 0;
495 
496     if (!ptr) {
497         return;
498     }
499 
500     HAL_MutexLock(mutex_mem_stats);
501 
502     pos = NULL;
503     list_for_each_entry_safe(pos, next, &mem_recs, list, OS_malloc_record)
504     {
505         if (pos->buf == ptr) {
506             found = 1;
507             break;
508         }
509     }
510 
511     if (!found) {
512         pos = NULL;
513     }
514 
515     if (NULL == pos) {
516         log_warning("utils", "Cannot find %p allocated! Skip stat ...", ptr);
517 
518         HAL_MutexUnlock(mutex_mem_stats);
519         return;
520     } else {
521         iterations_freed += 1;
522         iterations_in_use -= 1;
523 
524         bytes_total_freed += pos->buflen;
525         bytes_total_in_use -= pos->buflen;
526         _count_free_internal(ptr, pos);
527 
528         if (pos->buf && pos->buflen > 0) {
529             memset(pos->buf, 0xEE, pos->buflen);
530         }
531         pos->buf = 0;
532         pos->buflen = 0;
533         pos->func = "";
534         pos->line = 0;
535 #if defined(__UBUNTU_SDK_DEMO__)
536         pos->bt_level = 0;
537         HAL_Free(pos->bt_symbols);
538         pos->bt_symbols = 0;
539 #endif
540 
541         list_del(&pos->list);
542         HAL_Free(pos);
543     }
544     HAL_MutexUnlock(mutex_mem_stats);
545     HAL_Free(ptr);
546 }
547 
LITE_malloc_routine(int size,...)548 void *LITE_malloc_routine(int size, ...)
549 {
550     int magic = 0;
551     char *module_name = NULL;
552 
553     va_list ap;
554     va_start(ap, size);
555     magic = va_arg(ap, int);
556     if (MEM_MAGIC == magic) {
557         module_name = va_arg(ap, char *);
558     }
559     va_end(ap);
560 
561     return LITE_malloc(size, magic, module_name);
562 }
563 
LITE_calloc_routine(size_t n,size_t s,...)564 void *LITE_calloc_routine(size_t n, size_t s, ...)
565 {
566     int magic = 0;
567     char *module_name = NULL;
568 
569     va_list ap;
570     va_start(ap, s);
571     magic = va_arg(ap, int);
572     if (MEM_MAGIC == magic) {
573         module_name = va_arg(ap, char *);
574     }
575     va_end(ap);
576 
577     return LITE_malloc(n * s, magic, module_name);
578     ;
579 }
580 
LITE_free_routine(void * ptr)581 void LITE_free_routine(void *ptr)
582 {
583     LITE_free(ptr);
584 }
585 
LITE_dump_malloc_free_stats(int level)586 void LITE_dump_malloc_free_stats(int level)
587 {
588     OS_malloc_record *pos;
589     module_mem_t *module_pos, *tmp;
590     module_mem_t *unknown_mod = NULL;
591 
592     if (level > LITE_get_loglevel()) {
593         return;
594     }
595 
596     utils_debug("");
597     utils_debug("---------------------------------------------------");
598     utils_debug(". bytes_total_allocated:    %d", bytes_total_allocated);
599     utils_debug(". bytes_total_freed:        %d", bytes_total_freed);
600     utils_debug(". bytes_total_in_use:       %d", bytes_total_in_use);
601     utils_warning(". bytes_max_allocated:      %d", bytes_max_allocated);
602     utils_info(". bytes_max_in_use:         %d", bytes_max_in_use);
603     utils_debug(". iterations_allocated:     %d", iterations_allocated);
604     utils_debug(". iterations_freed:         %d", iterations_freed);
605     utils_debug(". iterations_in_use:        %d", iterations_in_use);
606     utils_debug(". iterations_max_in_use:    %d", iterations_max_in_use);
607     utils_debug("---------------------------------------------------");
608     utils_debug("");
609 
610     _mem_sort_module_pos(&mem_module_statis);
611 
612     LITE_printf("\r\n");
613     LITE_printf(
614         "|               |  max_in_use          |  max_allocated   |  "
615         "total_allocated      |  total_free\r\n");
616     LITE_printf(
617         "|---------------|----------------------|------------------|-----------"
618         "------------|----------------------\r\n");
619     list_for_each_entry_safe(module_pos, tmp, &mem_module_statis, list,
620                              module_mem_t)
621     {
622         if (module_pos) {
623             LITE_printf(
624                 "| %-13s | %6d bytes / %-5d |    %6d bytes  | %6d bytes / %-5d "
625                 " | %6d bytes / %-5d     \r\n",
626                 module_pos->mem_statis.module_name,
627                 module_pos->mem_statis.bytes_max_in_use,
628                 module_pos->mem_statis.iterations_max_in_use,
629                 module_pos->mem_statis.bytes_max_allocated,
630                 module_pos->mem_statis.bytes_total_allocated,
631                 module_pos->mem_statis.iterations_allocated,
632                 module_pos->mem_statis.bytes_total_freed,
633                 module_pos->mem_statis.iterations_freed);
634             /*
635                         LITE_printf("\x1B[1;32mMODULE_NAME: [%s]\x1B[0m\r\n",
636                module_pos->mem_statis.module_name);
637                         LITE_printf("---------------------------------------------------\r\n");
638                         LITE_printf(". bytes_total_allocated:    %d\r\n",
639                module_pos->mem_statis.bytes_total_allocated); LITE_printf(".
640                bytes_total_freed:        %d\r\n",
641                module_pos->mem_statis.bytes_total_freed); LITE_printf(".
642                bytes_total_in_use:       %d\r\n",
643                module_pos->mem_statis.bytes_total_in_use); LITE_printf(".
644                bytes_max_allocated:      %d\r\n",
645                module_pos->mem_statis.bytes_max_allocated); LITE_printf(".
646                bytes_max_in_use:         %d\r\n",
647                module_pos->mem_statis.bytes_max_in_use); LITE_printf(".
648                iterations_allocated:     %d\r\n",
649                module_pos->mem_statis.iterations_allocated); LITE_printf(".
650                iterations_freed:         %d\r\n",
651                module_pos->mem_statis.iterations_freed); LITE_printf(".
652                iterations_in_use:        %d\r\n",
653                module_pos->mem_statis.iterations_in_use); LITE_printf(".
654                iterations_max_in_use:    %d\r\n",
655                module_pos->mem_statis.iterations_max_in_use);
656                         LITE_printf("---------------------------------------------------\r\n");
657             */
658             if (!strcmp(module_pos->mem_statis.module_name, "unknown")) {
659                 unknown_mod = module_pos;
660             } else {
661                 HAL_Free(module_pos->mem_statis.calling_stack.func_name);
662             }
663         }
664     }
665 
666     if (unknown_mod) {
667         calling_stack_t *call_pos, *tmp;
668         LITE_printf("\r\n");
669         LITE_printf("\x1B[1;33mMissing module-name references:\x1B[0m\r\n");
670         LITE_printf("---------------------------------------------------\r\n");
671 
672         list_for_each_entry_safe(
673             call_pos, tmp, &unknown_mod->mem_statis.calling_stack.func_head,
674             func_head, calling_stack_t)
675         {
676             if (call_pos->func_name) {
677                 LITE_printf(". \x1B[1;31m%s \x1B[0m Ln:%d\r\n",
678                             call_pos->func_name, call_pos->line);
679 
680                 /* free memery of func_name and calling_stack */
681                 HAL_Free(call_pos->func_name);
682                 list_del(&call_pos->func_head);
683                 HAL_Free(call_pos);
684             }
685         }
686         LITE_printf("\r\n");
687     }
688 
689     list_for_each_entry_safe(module_pos, tmp, &mem_module_statis, list,
690                              module_mem_t)
691     {
692         list_del(&module_pos->list);
693         HAL_Free(module_pos);
694     }
695 
696     LITE_printf("\r\n");
697 
698     if (LITE_get_loglevel() == level) {
699         int j;
700         int cnt = 0;
701 
702         list_for_each_entry(pos, &mem_recs, list, OS_malloc_record)
703         {
704             if (pos->buf) {
705                 LITE_printf("%4d. %-24s Ln:%-5d @ %p: %4d bytes [", ++cnt,
706                             pos->func, pos->line, pos->buf, pos->buflen);
707                 for (j = 0; j < 32 && j < pos->buflen; ++j) {
708                     char c;
709 
710                     c = *(char *)(pos->buf + j);
711                     if (c < ' ' || c > '~') {
712                         c = '.';
713                     }
714                     LITE_printf("%c", c);
715                 }
716                 LITE_printf("]\r\n");
717 
718 #if defined(__UBUNTU_SDK_DEMO__)
719                 {
720                     int k;
721                     LITE_printf("\r\n");
722                     for (k = 0; k < pos->bt_level; ++k) {
723                         int m;
724                         const char *p = strchr(pos->bt_symbols[k], '(');
725 
726                         if (p[1] == ')') {
727                             continue;
728                         }
729                         LITE_printf("    ");
730                         for (m = 0; m < k; ++m) {
731                             LITE_printf("  ");
732                         }
733 
734                         LITE_printf("%s\r\n", p);
735                     }
736                 }
737 #endif
738                 LITE_printf("\r\n");
739             }
740         }
741     }
742 
743     return;
744 }
745 
LITE_get_mem_mutex(void)746 void **LITE_get_mem_mutex(void)
747 {
748     return &mutex_mem_stats;
749 }
750 
751 #else
LITE_malloc_internal(const char * f,const int l,int size,...)752 void *LITE_malloc_internal(const char *f, const int l, int size, ...)
753 {
754     void *ptr = NULL;
755 
756     ptr = aos_malloc(size);
757     if (NULL == ptr) {
758         return NULL;
759     }
760     memset(ptr, 0, size);
761     return ptr;
762 }
763 
LITE_free_internal(void * ptr)764 void LITE_free_internal(void *ptr)
765 {
766     aos_free(ptr);
767 }
768 #endif
769