⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memcheck.c

📁 memory test check for embeded linux
💻 C
📖 第 1 页 / 共 5 页
字号:
   void *ptr;   ptr = memcheck_allocator(file,                            line,                            calloc_function,                            addr,                            trace,                            NULL,                            size * n);   if(ptr != NULL && n * size != 0)   {      memset(ptr, 0, n * size);   }   return ptr;}static void *memcheck_realloc_internal(const char *file,                                       int line,                                       const void *addr,                                       const struct backtrace *trace,                                       void *ptr,                                       size_t size){   return memcheck_allocator(file,                             line,                             realloc_function,                             addr,                             trace,                             ptr,                             size);}static void memcheck_free_internal(const char *file,                                   int line,                                   const void *addr,                                   const struct backtrace *trace,                                   const void *ptr){   memcheck_allocator(file,                      line,                      free_function,                      addr,                      trace,                      ptr,                      0);}static void memcheck_cfree_internal(const char *file,                                    int line,                                    const void *addr,                                    const struct backtrace *trace,                                    const void *ptr){   memcheck_allocator(file,                      line,                      cfree_function,                      addr,                      trace,                      ptr,                      0);}static void *memcheck_valloc_internal(const char *file,                                      int line,                                      const void *addr,                                      const struct backtrace *trace,                                      size_t size){   return memcheck_allocator(file,                             line,                             valloc_function,                             addr,                             trace,                             NULL,                             size);}static void *memcheck_memalign_internal(const char *file,                                        int line,                                        const void *addr,                                        const struct backtrace *trace,                                        size_t boundary,                                        size_t size){   (void)boundary;   return memcheck_allocator(file,                             line,                             memalign_function,                             addr,                             trace,                             NULL,                             size);}static int memcheck_posix_memalign_internal(const char *file,                                            int line,                                            const void *addr,                                            const struct backtrace *trace,                                            void **memptr,                                            size_t alignment,                                            size_t size){   int retval;   void *ptr;   if((alignment % sizeof(void *)) == 0 && (size & (size - 1)) == 0)   {      if((ptr = memcheck_memalign_internal(file,                                           line,                                           addr,                                           trace,                                           alignment,                                           size)) != NULL)      {         *memptr = ptr;         retval = 0;      }      else      {         retval = errno;      }   }   else   {      retval = EINVAL;   }   return retval;}static void *memcheck_allocator(const char *file,                                int line,                                int func,                                const void *addr,                                const struct backtrace *trace,                                const void *ptr,                                size_t nsize){#ifdef HAVE_SIGACTION   sigaction_t act;#endif   struct caller caller;   struct meminfo *omem;   struct meminfo *nmem;   size_t opages;   size_t npages;   size_t upages;   size_t osize;   size_t ocount;   void *optr;   void *nptr;   int logged;   int history;   logged = MEMCHECK_NONE;   history = MEMCHECK_NONE;   /* Initialize, if first time.  */   if(memcheck_pagesize == 0)   {      memcheck_initialize();   }#ifdef HAVE_SIGACTION   else   {      if(!sigaction(SIGSEGV, NULL, &act))      {# if defined(HAVE_SIGACTION_T_SA_SIGACTION) \  || defined(HAVE_STRUCT_SIGACTION_SA_SIGACTION)         if(act.sa_sigaction != memcheck_act_segv[0].sa_sigaction)         {            memcheck_act_segv[0].sa_sigaction = (sa_function)memcheck_sig2;# elif defined(HAVE_SIGACTION_T_SA_HANDLER) \  || defined(HAVE_STRUCT_SIGACTION_SA_HANDLER)         if(act.sa_handler != memcheck_act_segv[0].sa_handler)         {            memcheck_act_segv[0].sa_handler = (sa_function)memcheck_sig2;# endif            /* Somebody removed our segv hander, put it back.  */            if(memcheck_act_segv[2].sa_handler == NULL)            {               if(sigaction(SIGSEGV,                            &memcheck_act_segv[0],                            &memcheck_act_segv[2]))               {                  memcheck_error("sigaction");               }            }            memcheck_reinstalled_handler = 1;         }      }      else      {         memcheck_error("sigaction");      }      if(!sigaction(SIGBUS, NULL, &act))      {# if defined(HAVE_SIGACTION_T_SA_SIGACTION) \  || defined(HAVE_STRUCT_SIGACTION_SA_SIGACTION)         if(act.sa_sigaction != memcheck_act_bus[0].sa_sigaction)         {            memcheck_act_bus[0].sa_sigaction = (sa_function)memcheck_sig2;# elif defined(HAVE_SIGACTION_T_SA_HANDLER) \  || defined(HAVE_STRUCT_SIGACTION_SA_HANDLER)         if(act.sa_handler != memcheck_act_bus[0].sa_handler)         {            memcheck_act_bus[0].sa_handler = (sa_function)memcheck_sig2;# endif            /* Somebody removed our bus hander, put it back.  */            if(memcheck_act_bus[2].sa_handler == NULL)            {               if(sigaction(SIGBUS, &memcheck_act_bus[0], &memcheck_act_bus[2]))               {                  memcheck_error("sigaction");               }            }            memcheck_reinstalled_handler = 1;         }      }      else      {         memcheck_error("sigaction");      }   }#endif#ifdef HAVE_BACKTRACE   if(trace != NULL)   {      memcpy(&caller.trace, trace, sizeof(caller.trace));   }   else   {      (void)trace;      memset(&caller.trace, 0, sizeof(caller.trace));   }#else   (void)trace;#endif   caller.addr = addr;   caller.file = file;   caller.line = line;   caller.func = func;   /* Check for NULL pointer on deallocations.  */   if(ptr == NULL && memcheck_functions[func].type & free_type)   {      memcheck_log_info(MEMCHECK_INFO, 1, "NULL", ptr, &caller);      logged = logged > MEMCHECK_INFO ? logged : MEMCHECK_INFO;   }   if(memcheck_functions[func].type & alloc_type)   {      /* Check for zero size on allocations.  */      if(nsize == 0)      {         memcheck_log_info(MEMCHECK_INFO, 1, "Zero size", ptr, &caller);         logged = logged > MEMCHECK_INFO ? logged : MEMCHECK_INFO;      }      else if(nsize >= memcheck_config.large && memcheck_config.large > 0)      {         memcheck_log_info(MEMCHECK_INFO, 1, "Large allocation", ptr, &caller);         logged = logged > MEMCHECK_INFO ? logged : MEMCHECK_INFO;      }   }   /* Retrieve info for old allocation.  */   if(ptr != NULL && memcheck_functions[func].type & free_type)   {      omem = meminfo_from_ptr(ptr);      if(!memcheck_unprotect(omem))      {         if(memcheck_check_sentry(omem))         {            memcheck_log_info(MEMCHECK_ERROR,                              1,                              memcheck_config.underruns                              ? "Detected overrun"                              : "Detected underrun",                              ptr, &caller);            history = history > MEMCHECK_ERROR ? history : MEMCHECK_ERROR;            logged = logged > MEMCHECK_ERROR ? logged : MEMCHECK_ERROR;         }         optr = omem->ptr;         if(optr != ptr)         {            memcheck_log_info(MEMCHECK_ERROR, 1, "Invalid", ptr, &caller);            logged = logged > MEMCHECK_ERROR ? logged : MEMCHECK_ERROR;         }         osize = omem->size;         opages = omem->pages;         ocount = omem->count;         /* Check for old allocation already freed.  */         if(!omem->inuse)         {            memcheck_log_info(MEMCHECK_ERROR, 1, "Already freed", ptr, &caller);            history = history > MEMCHECK_ERROR ? history : MEMCHECK_ERROR;            logged = logged > MEMCHECK_ERROR ? logged : MEMCHECK_ERROR;         }      }      else      {         omem = NULL;         optr = NULL;         osize = 0;         opages = 0;         ocount = 0;         memcheck_log_info(MEMCHECK_ERROR, 1, "Invalid", ptr, &caller);         logged = logged > MEMCHECK_ERROR ? logged : MEMCHECK_ERROR;      }   }   else   {      omem = NULL;      optr = NULL;      osize = 0;      opages = 0;      ocount = 0;   }   /* Calculate number of pages for new allocation.  */   if(memcheck_functions[func].type & alloc_type)   {      /* Always need an info page.  */      npages = 1;      if(nsize > 0)      {         npages += memcheck_user_pages(nsize);      }      if(ocount >= MAX_REALLOC_CALL)      {         npages += 1                + ((ocount - MAX_REALLOC_CALL + 1) * sizeof(struct caller))                   / memcheck_pagesize;      }      if(opages == npages && !memcheck_config.churn)      /* If page count isn't changing and we aren't "churning".  */      {         nmem = omem;         if(osize == nsize)         /* If byte count isn't changing, return the original pointer.  */         {            nptr = optr;         }         else         /* Relocate the pointer on the same page.  */         {            memcheck_update(nmem, &caller);            memcheck_setup(nmem, npages, nsize);            nptr = nmem->ptr;         }      }      else      /* The page count _is_ changing or we _are_ "churning".  */      {         if((nmem = memcheck_get(npages)) != NULL)         /* Got a new block of memory.  */         {            if(omem != NULL)            {               /* Continue tracking, even if the actual data moves.  */               memcpy(nmem, omem, memcheck_pagesize);               if(ocount >= MAX_REALLOC_CALL)               {                  upages = memcheck_user_pages(nsize);                  /* Set the realloc overflow area after                     the end of the user area.  */                  nmem->realloc2 = (struct caller *)((char *)nmem                                    + memcheck_pagesize * (1 + upages));                  if(ocount > MAX_REALLOC_CALL)                  {                     /* Continue tracking the realloc overflow area as well.  */                     memcpy(nmem->realloc2,                            omem->realloc2,                            (ocount - MAX_REALLOC_CALL)                               * sizeof(struct caller));                  }               }               memcheck_update(nmem, &caller);            }            else            {               memcheck_insert(nmem, &caller);            }            memcheck_setup(nmem, npages, nsize);            nptr = nmem->ptr;         }         else         /* New block failed.  */         {            memcheck_log_info(MEMCHECK_ERROR, 1, "Out of memory", ptr, &caller);            logged = logged > MEMCHECK_ERROR ? logged : MEMCHECK_ERROR;            nptr = NULL;         }      }   }   else   {      nmem = NULL;      nptr = NULL;      nsize = 0;      npages = 0;   }   if(logged)   {      if(memcheck_config.backtrace)      {         memcheck_get_symbols(logged, 1, trace);      }      if(history)      {         memcheck_history(history, 1, omem);      }   }   /* Old and new block both have size and new pointer exists.  */   if(osize > 0 && nsize > 0 && nptr != NULL && optr != nptr)   {      memmove(nptr, optr, osize > nsize ? nsize : osize);   }   /* Old block exists and isn't being retained.  */   if(omem != NULL && omem != nmem && omem->inuse)   {      memcheck_delete(omem, &caller);      memcheck_put(omem);   }   if(nmem != NULL)   {      memcheck_place_sentry(nmem);      memcheck_protect(nmem, PROT_READ | PROT_WRITE);   }   return nptr;}static int memcheck_check_sentry(struct meminfo *mem){   long sentry;   int retval;   if(mem->sentry != NULL)   {      /* Use memcpy instead of cast+assignment *       * due to possible mis-alignment.        */      memcpy(&sentry, mem->sentry, sizeof(sentry));      if(sentry != memcheck_sentry)      {         retval = 1;      }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -