Ignore:
Timestamp:
09/02/21 17:06:35 (3 years ago)
Author:
ymipsl
Message:

Revisiting Memory tracking :

  • MemTrack? has been improved
    • Not need anymore to use private external libaddr2line, fork addr2line process internaly and use bidrectionnale pipe to send stack adress et get in return the demangle stack name
    • Can use cxa_demangle in backup
  • Block memory leak report is output in separate file (xios_xxx.mem),memory block are ordonned in decreasing size.
  • Possibility to output only the n bigest bloc with : "memtrack_blocs" xios parameters
  • Possibility to output only bloc over a given size with : "memtrack_size" xios parameters
  • Implement new method to retrieve the memory consumed in a time interval very similarely to xios timer :

CMemTracker("xios").resume()
CMemTracker("xios").suspend() ;
etc....

YM

File:
1 edited

Legend:

Unmodified
Added
Removed
  • XIOS/dev/dev_ym/XIOS_COUPLING/src/memtrack.cpp

    r1158 r2212  
    4545#include <string> 
    4646#include <execinfo.h> 
    47  
     47#include <cxxabi.h> 
     48#include <dlfcn.h> 
     49#include <map> 
     50#include <fstream> 
    4851#include "memtrack.hpp" 
     52#include "log.hpp" 
     53#include "addr2line.hpp" 
    4954#undef new    // IMPORTANT! 
    5055 
    51 extern "C" 
    52 { 
    53   void addr2line(const char *file_name, char** addr, int naddr) ; 
    54 #ifdef XIOS_MEMTRACK_LIGHT 
    55   void addr2line(const char *file_name, char** addr, int naddr) {}  
    56 #endif 
    57 } 
     56 
    5857/* ------------------------------------------------------------ */ 
    5958/* -------------------- namespace MemTrack -------------------- */ 
     
    9897         
    9998            void Stamp(char const *filename, int lineNum, char const *typeName); 
    100             void backTrace(void) ; 
    101          
     99            void backTrace(std::ofstream& memReport, xios::CAddr2line& addr2line) ; 
     100            void backTrace(std::ofstream& memReport) ; 
     101 
    102102            static void AddNode(BlockHeader *node); 
    103103            static void RemoveNode(BlockHeader *node); 
     
    139139    } 
    140140 
    141     void BlockHeader::backTrace(void) 
     141 
     142    void BlockHeader::backTrace(std::ofstream& memReport) 
     143    { 
     144        char** strings ; 
     145        strings = backtrace_symbols(stackArray, this->stackSize); 
     146        int stackSize=this->stackSize-3 ; 
     147        char* buffer ; 
     148        char* outputBuffer ; 
     149        size_t length=10 ; 
     150        outputBuffer = (char*) malloc(length) ; 
     151        int status ; 
     152        Dl_info info; 
     153        for(int i=0;i<stackSize;i++)  
     154        { 
     155            if (dladdr(stackArray[i+3], &info)) 
     156            { 
     157              buffer=abi::__cxa_demangle(info.dli_sname,outputBuffer,&length,&status ); 
     158              if (buffer!=nullptr)  
     159              { 
     160                memReport<<buffer<<std::endl ; 
     161                outputBuffer=buffer ; 
     162              } 
     163              else if (info.dli_sname!=nullptr) memReport<<info.dli_sname<<std::endl ; 
     164              else memReport<<strings[i+3]<<std::endl ; 
     165            } 
     166            else memReport<<strings[i+3]<<std::endl ; 
     167        } 
     168        free(buffer) ; 
     169        free(strings) ; 
     170    } 
     171 
     172    void BlockHeader::backTrace(std::ofstream& memReport, xios::CAddr2line& addr2line) 
    142173    {    
    143174         
    144 //        oss<<"addr2line -C -f -i -s -e ../bin/test_client.exe " ; 
    145         char *addr ; 
    146         char buffer[20] ; 
    147         addr=buffer ; 
    148         for(int i=0;i<stackSize;i++)  
    149         { 
    150           std::ostringstream oss ; 
    151           oss<<stackArray[i] ; 
    152           strcpy(addr,oss.str().c_str()) ; 
    153           addr2line("/proc/self/exe",&addr,1) ; 
    154         } 
     175      int stackSize=this->stackSize-3 ; 
     176       
     177      for(int i=0;i<stackSize;i++) 
     178      { 
     179        std::ostringstream address; 
     180        address << stackArray[i+3]; 
     181        addr2line.write(address.str()) ; 
     182        std::string out ; 
     183        addr2line.read(out) ; 
     184        memReport<<out<<std::endl ; 
     185      } 
    155186    } 
    156187    /* ---------------------------------------- BlockHeader AddNode */ 
     
    439470    /* ---------------------------------------- TrackDumpBlocks */ 
    440471 
    441     void TrackDumpBlocks() 
     472    void TrackDumpBlocks(std::ofstream& memReport, size_t memtrack_blocks, size_t memtrack_size ) 
    442473    { 
    443474        // Get an array of pointers to all extant blocks. 
     475        std::ostringstream ostr ; 
    444476        size_t numBlocks = BlockHeader::CountBlocks(); 
    445477        BlockHeader **ppBlockHeader = 
    446478            (BlockHeader **)calloc(numBlocks, sizeof(*ppBlockHeader)); 
    447479        BlockHeader::GetBlocks(ppBlockHeader); 
    448  
    449480        // Dump information about the memory blocks. 
    450         printf("\n"); 
    451         printf("=====================\n"); 
    452         printf("Current Memory Blocks\n"); 
    453         printf("=====================\n"); 
    454         printf("\n"); 
     481         
     482        memReport<<std::endl; 
     483        memReport<<"=====================" <<std::endl ; 
     484        memReport<<"Current Memory Blocks" <<std::endl ; 
     485        memReport<<"=====================" <<std::endl ; 
     486        memReport<<std::endl ; 
     487        char strbuff[10000] ; 
     488        std::multimap<size_t,BlockHeader *,std::greater<int>> orderedBlocks ; 
    455489        for (size_t i = 0; i < numBlocks; i++) 
    456490        { 
    457             BlockHeader *pBlockHeader = ppBlockHeader[i]; 
     491          BlockHeader *pBlockHeader = ppBlockHeader[i]; 
     492          size_t size = pBlockHeader->GetRequestedSize(); 
     493          orderedBlocks.insert({size,pBlockHeader}) ; 
     494        } 
     495         
     496        xios::CAddr2line myaddr2line ; 
     497        size_t i = 0 ; 
     498        for(auto& it : orderedBlocks) 
     499        { 
     500            BlockHeader *pBlockHeader = it.second ; 
    458501            char const *typeName = pBlockHeader->GetTypeName(); 
    459502            size_t size = pBlockHeader->GetRequestedSize(); 
    460503            char const *fileName = pBlockHeader->GetFilename(); 
    461504            int lineNum = pBlockHeader->GetLineNum(); 
    462             printf("*** #%-6d %5d bytes %-50s\n", i, size, typeName); 
    463             printf("... %s:%d\n", fileName, lineNum); 
    464             pBlockHeader->backTrace(); 
    465         } 
    466  
     505            if (memtrack_blocks>0 && i>memtrack_blocks) break ;             
     506            if (memtrack_size>0 && size<memtrack_size) break ;             
     507             
     508            sprintf(strbuff,"*** #%-6d %5d bytes %-50s\n", i, size, typeName); 
     509            memReport<<strbuff ; 
     510            sprintf(strbuff,"... %s:%d\n", fileName, lineNum); 
     511            memReport<<strbuff ; 
     512            //pBlockHeader->backTrace(memReport, myaddr2line); 
     513            pBlockHeader->backTrace(memReport); 
     514            i++ ; 
     515        } 
    467516        // Clean up. 
    468517        free(ppBlockHeader); 
Note: See TracChangeset for help on using the changeset viewer.