open-source-search-engine/Profiler.h

300 lines
9.4 KiB
C
Raw Normal View History

2013-08-03 00:12:24 +04:00
#define MAX_TOPICS_PER_TERM 28
#define MAX_ALLOWED_TOPICS 100
#define EI_NIDENT 16
#ifndef _PROFILER_H_
#define _PROFILER_H_
#define SHT_SYMTAB 2
#define SHT_DYNSYM 11
#include "TcpServer.h"
#include "HttpRequest.h"
#include "Parms.h"
#include "SafeBuf.h"
#include "Pages.h"
//#include "HashTableT.h"
#include "HashTableX.h"
typedef struct elf_internal_ehdr {
unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */
2014-11-11 01:45:11 +03:00
uint32_t e_entry; /* Entry point virtual address */
uint32_t e_phoff; /* Program header table file offset */
uint32_t e_shoff; /* Section header table file offset */
uint32_t e_version; /* Identifies object file version */
uint32_t e_flags; /* Processor-specific flags */
uint16_t e_type; /* Identifies object file type */
uint16_t e_machine; /* Specifies required architecture */
uint16_t e_ehsize; /* ELF header size in bytes */
uint16_t e_phentsize; /* Program header table entry size */
uint16_t e_phnum; /* Program header table entry count */
uint16_t e_shentsize; /* Section header table entry size */
uint16_t e_shnum; /* Section header table entry count */
uint16_t e_shstrndx; /* Section header string table index */
2013-08-03 00:12:24 +04:00
} Elf_Internal_Ehdr;
typedef struct {
unsigned char e_ident[16]; /* ELF "magic number" */
unsigned char e_type[2]; /* Identifies object file type */
unsigned char e_machine[2]; /* Specifies required architecture */
unsigned char e_version[4]; /* Identifies object file version */
unsigned char e_entry[4]; /* Entry point virtual address */
unsigned char e_phoff[4]; /* Program header table file offset */
unsigned char e_shoff[4]; /* Section header table file offset */
unsigned char e_flags[4]; /* Processor-specific flags */
unsigned char e_ehsize[2]; /* ELF header size in bytes */
unsigned char e_phentsize[2]; /* Program header table entry size */
unsigned char e_phnum[2]; /* Program header table entry count */
unsigned char e_shentsize[2]; /* Section header table entry size */
unsigned char e_shnum[2]; /* Section header table entry count */
unsigned char e_shstrndx[2]; /* Section header string table index */
} Elf32_External_Ehdr;
typedef struct elf_internal_shdr {
unsigned int sh_name; /* Section name, index in string tbl */
unsigned int sh_type; /* Type of section */
2014-11-11 01:45:11 +03:00
uint32_t sh_flags; /* Miscellaneous section attributes */
uint32_t sh_addr; /* Section virtual addr at execution */
uint32_t sh_size; /* Size of section in bytes */
uint32_t sh_entsize; /* Entry size if section holds table */
uint32_t sh_link; /* Index of another section */
uint32_t sh_info; /* Additional section information */
int32_t sh_offset; /* Section file offset */
2013-08-03 00:12:24 +04:00
unsigned int sh_addralign; /* Section alignment */
/* The internal rep also has some cached info associated with it.
asection * bfd_section; Associated BFD section.
PTR contents; Section contents. */
} Elf_Internal_Shdr;
typedef struct {
unsigned char sh_name[4]; /* Section name, index in string tbl */
unsigned char sh_type[4]; /* Type of section */
unsigned char sh_flags[4]; /* Miscellaneous section attributes */
unsigned char sh_addr[4]; /* Section virtual addr at execution */
unsigned char sh_offset[4]; /* Section file offset */
unsigned char sh_size[4]; /* Size of section in bytes */
unsigned char sh_link[4]; /* Index of another section */
unsigned char sh_info[4]; /* Additional section information */
unsigned char sh_addralign[4];/* Section alignment */
unsigned char sh_entsize[4]; /* Entry size if section holds table */
} Elf32_External_Shdr;
typedef struct elf_internal_sym {
2014-11-11 01:45:11 +03:00
uint32_t st_value; /* Value of the symbol */
uint32_t st_size; /* Associated symbol size */
uint32_t st_name; /* Symbol name, index in string tbl */
2013-08-03 00:12:24 +04:00
unsigned char st_info; /* Type and binding attributes */
unsigned char st_other; /* No defined meaning, 0 */
2014-11-11 01:45:11 +03:00
uint16_t st_shndx; /* Associated section index */
2013-08-03 00:12:24 +04:00
} Elf_Internal_Sym;
typedef struct {
unsigned char st_name[4]; /* Symbol name, index in string tbl */
unsigned char st_value[4]; /* Value of the symbol */
unsigned char st_size[4]; /* Associated symbol size */
unsigned char st_info[1]; /* Type and binding attributes */
unsigned char st_other[1]; /* No defined meaning, 0 */
unsigned char st_shndx[2]; /* Associated section index */
} Elf32_External_Sym;
struct FnInfo {
char m_fnName[256];
2014-11-11 01:45:11 +03:00
uint32_t m_timesCalled;
uint32_t m_totalTimeTaken;
uint32_t m_maxTimeTaken;
uint32_t m_numCalledFromThread;
uint32_t m_maxBlockedTime;
2013-08-03 00:12:24 +04:00
const char *m_lastQpoll;
const char *m_prevQpoll;
2014-10-30 22:36:39 +03:00
int64_t m_startTimeLocal;
int64_t m_startTime;
int64_t m_lastPauseTime;
2014-11-11 01:45:11 +03:00
int32_t m_inFunction;
2013-08-03 00:12:24 +04:00
};
struct QuickPollInfo {
const char *m_caller;
2014-11-11 01:45:11 +03:00
int32_t m_lineno;
2013-08-03 00:12:24 +04:00
const char *m_last;
2014-11-11 01:45:11 +03:00
int32_t m_lastlineno;
int32_t m_timeAcc;
int32_t m_maxTime;
int32_t m_times;
2013-08-03 00:12:24 +04:00
};
struct HitEntry {
char *funcName;
char *file;
uint32_t fileHash;
uint32_t line;
uint32_t numHits;
uint32_t numHitsPerFunc;
uint32_t address;
uint32_t baseAddress;
uint32_t missedQuickPolls;
uint32_t missedQuickPollsPerFunc;
};
class FrameTrace {
public:
FrameTrace();
~FrameTrace();
FrameTrace *set(const uint32_t addr);
FrameTrace *add(const uint32_t baseAddr);
void dump( SafeBuf *out,
const uint32_t level = 0,
uint32_t printStart = 0) const;
uint32_t getPrintLen(const uint32_t level = 0) const;
uint32_t address;
static const uint16_t MAX_CHILDREN = 64;
FrameTrace *m_children[MAX_CHILDREN];
uint32_t m_numChildren;
uint32_t hits;
uint32_t missQuickPoll;
};
class Profiler {
public:
Profiler();
~Profiler();
bool reset();
bool init();
2014-10-30 22:36:39 +03:00
bool addQuickPoll(int64_t took, const char* caller);
2014-11-11 01:45:11 +03:00
bool startTimer(int32_t address, const char* caller);
bool pause(const char *caller, int32_t lineno, int32_t took);
2013-08-03 00:12:24 +04:00
bool unpause();
//This function should get the function name from nm / addr2line
2014-11-11 01:45:11 +03:00
bool endTimer(int32_t address,
2013-08-03 00:12:24 +04:00
const char *caller,
bool isThread=false);
bool printInfo(SafeBuf *sb,
2014-11-11 01:45:11 +03:00
//int32_t user,
2013-08-03 00:12:24 +04:00
char *username,
char *pwd,
char *coll,
int sorts,
int sort10,
int qpreset,
int profilerreset);
bool printRealTimeInfo(SafeBuf *sb,
2014-11-11 01:45:11 +03:00
//int32_t user,
2013-08-03 00:12:24 +04:00
char *username,
char *pwd,
char *coll,
int realTimeSortMode,
int realTimeShowAll);
void resetLastQpoll() {m_lastQpoll = "main loop"; m_lastQpollLine =0;}
char *getFnName(PTRTYPE address,int32_t *nameLen=NULL);
2013-08-03 00:12:24 +04:00
//Functions for reading the symbol table of gb,
//which is a 32-bit ELF file. These functions are
//a customized version of readelf program, found in
//GNU binutils, and works for 32-bit ELF files.
bool readSymbolTable();
static FrameTrace *getFrameTrace( void **trace,
const uint32_t numFrames);
static FrameTrace *updateRealTimeData( void **trace,
const uint32_t numFrames,
uint32_t **ptr);
static void checkMissedQuickPoll( FrameTrace *frame,
const uint32_t stackPtr,
uint32_t *ptr);
2015-01-21 03:02:10 +03:00
void getStackFrame(int sig);
2013-08-03 00:12:24 +04:00
void startRealTimeProfiler();
void stopRealTimeProfiler(const bool keepData=false);
void cleanup();
FrameTrace *getNewFrameTrace(const uint32_t addr);
bool m_realTimeProfilerRunning;
2015-01-21 03:02:10 +03:00
SafeBuf m_ipBuf;
2013-08-03 00:12:24 +04:00
protected:
bool processSymbolTable (FILE *file);
bool processSectionHeaders (FILE * file);
bool get32bitSectionHeaders (FILE * file);
bool getFileHeader (FILE * file);
2014-11-11 01:45:11 +03:00
//bool fnReset (HashTableT<uint32_t, FnInfo*> *m_fn);
2013-08-03 00:12:24 +04:00
FILE *m_file;
char *m_stringTable;
2014-11-11 01:45:11 +03:00
int32_t m_stringTableSize;
2013-08-03 00:12:24 +04:00
Elf_Internal_Ehdr m_elfHeader;
Elf_Internal_Shdr* m_sectionHeaders;
Elf_Internal_Sym* get32bitElfSymbols (FILE *file,
2014-11-11 01:45:11 +03:00
uint32_t offset,
uint32_t number);
2013-08-03 00:12:24 +04:00
2014-11-11 01:45:11 +03:00
uint32_t getByte (unsigned char * field,int size);
2013-08-03 00:12:24 +04:00
2014-11-11 01:45:11 +03:00
//HashTableT<uint32_t, FnInfo> m_fn;
//HashTableT<uint32_t, FnInfo> m_fnTmp[11];
//HashTableT<uint32_t, FnInfo*> m_activeFns;
//HashTableT<uint32_t, QuickPollInfo*> m_quickpolls;
2013-08-03 00:12:24 +04:00
// IP (Instruction Pointer) addresses, force to 64 bits
//HashTableX m_ipCountTable;
//SafeBuf m_quickpollMissBuf;
2013-08-03 00:12:24 +04:00
HashTableX m_fn;
HashTableX m_fnTmp[11];
HashTableX m_activeFns;
HashTableX m_quickpolls;
const char* m_lastQpoll;
2014-11-11 01:45:11 +03:00
int32_t m_lastQpollLine;
2013-08-03 00:12:24 +04:00
QuickPollInfo m_quickPollInfos[512];
2014-11-11 01:45:11 +03:00
int32_t m_lastQPUsed;
2013-08-03 00:12:24 +04:00
uint64_t m_fnTime[11];
2015-01-10 23:05:39 +03:00
public://private:
2013-08-03 00:12:24 +04:00
// Realtime profiler stuff
uint32_t getFuncBaseAddr(const uint32_t address);
uint32_t getFuncBaseAddr(const char *funcName);
static int rtDataLocationCmp(const void *A, const void *B);
static int rtHitCmp(const void *A, const void *B);
static int rtFuncHitCmp(const void *A, const void *B);
static int rtAddressCmp(const void *A, const void *B);
static int rtMissedQuickPolls(const void *A, const void *B);
static int rtMissedQuickPollPerFunc(const void *A, const void *B);
void sortRealTimeData(const uint8_t type, const uint32_t num);
uint32_t rtNumEntries;
HitEntry *hitEntries;
uint32_t *m_addressMap;
uint32_t m_addressMapSize;
uint32_t m_lastAddressMapIndex;
FrameTrace *m_rootFrame;
uint32_t m_lastDeltaAddress;
uint64_t m_lastDeltaAddressTime;
static const uint32_t MAX_FRAME_TRACES = 1024 * 64;
FrameTrace *m_frameTraces;
uint32_t m_numUsedFrameTraces;
};
extern Profiler g_profiler;
#endif