Skip to content

Commit 5f5c87e

Browse files
committed
Add funchook for malloc functions
1 parent 36ba5d5 commit 5f5c87e

File tree

4 files changed

+205
-0
lines changed

4 files changed

+205
-0
lines changed

src/dbg.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,30 @@ scopeLog(cfg_log_level_t level, const char *format, ...)
275275
return;
276276
}
277277

278+
void
279+
scopeBacktraceTest(void) {
280+
unw_cursor_t cursor;
281+
unw_context_t uc;
282+
unw_word_t ip;
283+
unw_getcontext(&uc);
284+
unw_init_local(&cursor, &uc);
285+
unw_step(&cursor); //skip first frame
286+
while(unw_step(&cursor) > 0) {
287+
char symbol[SYMBOL_BT_NAME_LEN];
288+
unw_word_t offset;
289+
290+
int ret = unw_get_reg(&cursor, UNW_REG_IP, &ip);
291+
if (ret) {
292+
continue;
293+
}
294+
//this is slow hashtable ?
295+
ret = unw_get_proc_name(&cursor, symbol, SYMBOL_BT_NAME_LEN, &offset);
296+
if (!ret) {
297+
scopeLogError("scopeBacktraceTest found symbol %s", symbol);
298+
}
299+
}
300+
}
301+
278302
void
279303
scopeBacktrace(cfg_log_level_t level)
280304
{

src/dbg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ extern bool g_ismusl;
7373
void scopeLog(cfg_log_level_t, const char *, ...) PRINTF_FORMAT(2,3);
7474
void scopeLogHex(cfg_log_level_t, const void *, size_t, const char *, ...) PRINTF_FORMAT(4,5);
7575
void scopeBacktrace(cfg_log_level_t);
76+
void scopeBacktraceTest(void);
7677

7778
#define scopeLogError(...) scopeLog(CFG_LOG_ERROR, __VA_ARGS__)
7879
#define scopeLogWarn(...) scopeLog(CFG_LOG_WARN, __VA_ARGS__)

src/fn.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,14 @@ typedef struct {
247247
DIR *(*opendir)(const char *);
248248
int (*closedir)(DIR *);
249249
struct dirent *(*readdir)(DIR *);
250+
void *(*malloc)(size_t);
251+
void (*free)(void *);
252+
void *(*calloc)(size_t, size_t);
253+
void *(*realloc)(void *, size_t);
254+
size_t (*malloc_usable_size)(void *);
255+
char *(*strdup)(const char *s);
256+
void *(*mmap)(void *, size_t, int, int, int, off_t);
257+
int (*munmap)(void *, size_t);
250258
#endif // __linux__
251259

252260
#if defined(__linux__) && defined(__STATX__)

src/wrap.c

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,14 @@ static got_list_t hook_list[] = {
8080

8181
static got_list_t inject_hook_list[] = {
8282
{"sigaction", NULL, &g_fn.sigaction},
83+
{"malloc", NULL, &g_fn.malloc},
84+
{"calloc", NULL, &g_fn.calloc},
85+
{"free", NULL, &g_fn.free},
86+
{"realloc", NULL, &g_fn.realloc},
87+
{"malloc_usable_size", NULL, &g_fn.malloc_usable_size},
88+
{"strdup", NULL, &g_fn.strdup},
89+
{"mmap", NULL, &g_fn.mmap},
90+
{"munmap", NULL, &g_fn.munmap},
8391
{"open", NULL, &g_fn.open},
8492
{"openat", NULL, &g_fn.openat},
8593
{"fopen", NULL, &g_fn.fopen},
@@ -1618,10 +1626,38 @@ initSigErrorHandler(void)
16181626
}
16191627
}
16201628

1629+
void wait_in_loop(void)
1630+
{
1631+
volatile int test = 1;
1632+
while(test){
1633+
sleep(1);
1634+
}
1635+
}
1636+
1637+
16211638
__attribute__((constructor)) void
16221639
init(void)
16231640
{
1641+
// wait_in_loop();
16241642
scope_init_vdso_ehdr();
1643+
g_fn.calloc = dlsym(RTLD_NEXT, "calloc");
1644+
if (!g_fn.calloc) g_fn.calloc = dlsym(RTLD_DEFAULT, "calloc");
1645+
g_fn.mmap = dlsym(RTLD_NEXT, "mmap");
1646+
if (!g_fn.mmap) g_fn.mmap = dlsym(RTLD_DEFAULT, "mmap");
1647+
g_fn.munmap = dlsym(RTLD_NEXT, "munmap");
1648+
if (!g_fn.munmap) g_fn.munmap = dlsym(RTLD_DEFAULT, "munmap");
1649+
g_fn.malloc = dlsym(RTLD_NEXT, "malloc");
1650+
if (!g_fn.malloc) g_fn.malloc = dlsym(RTLD_DEFAULT, "malloc");
1651+
g_fn.free = dlsym(RTLD_NEXT, "free");
1652+
if (!g_fn.free) g_fn.free = dlsym(RTLD_DEFAULT, "free");
1653+
g_fn.realloc = dlsym(RTLD_NEXT, "realloc");
1654+
if (!g_fn.realloc) g_fn.realloc = dlsym(RTLD_DEFAULT, "realloc");
1655+
g_fn.strdup = dlsym(RTLD_NEXT, "strdup");
1656+
if (!g_fn.strdup) g_fn.strdup = dlsym(RTLD_DEFAULT, "strdup");
1657+
1658+
g_fn.malloc_usable_size = dlsym(RTLD_NEXT, "malloc_usable_size");
1659+
if (!g_fn.malloc_usable_size) g_fn.malloc_usable_size = dlsym(RTLD_DEFAULT, "malloc_usable_size");
1660+
16251661
// Bootstrapping... we need to know if we're in musl so we can
16261662
// call the right initFn function...
16271663
{
@@ -1725,6 +1761,142 @@ sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
17251761
return g_fn.sigaction(signum, act, oldact);
17261762
}
17271763

1764+
static int call_backtrace = 0;
1765+
static size_t no_bytes_allocated;
1766+
static void *calloc_mem = NULL;
1767+
1768+
EXPORTON char *
1769+
strdup(const char *s) {
1770+
WRAP_CHECK(strdup, NULL);
1771+
1772+
char *str = g_fn.strdup(s);
1773+
1774+
if(g_log) {
1775+
size_t allocated_size = g_fn.malloc_usable_size(str);
1776+
no_bytes_allocated += allocated_size;
1777+
if (call_backtrace)
1778+
scopeBacktraceTest();
1779+
scopeLogError("function = %s allocate: %zu bytes\n. Total allocated size %zu bytes\n", __FUNCTION__, allocated_size, no_bytes_allocated);
1780+
}
1781+
1782+
return str;
1783+
}
1784+
1785+
EXPORTON void *
1786+
malloc(size_t size) {
1787+
WRAP_CHECK(malloc, NULL);
1788+
1789+
void *ptr = g_fn.malloc(size);
1790+
1791+
if(g_log) {
1792+
if (call_backtrace)
1793+
scopeBacktraceTest();
1794+
size_t allocated_size = g_fn.malloc_usable_size(ptr);
1795+
no_bytes_allocated += allocated_size;
1796+
1797+
scopeLogError("function = %s allocate: %zu bytes, requested %zu bytes. Total allocated size %zu bytes\n", __FUNCTION__, allocated_size, size, no_bytes_allocated);
1798+
}
1799+
1800+
return ptr;
1801+
}
1802+
1803+
EXPORTON void *
1804+
calloc(size_t nmemb, size_t size) {
1805+
1806+
if (g_fn.calloc == NULL) {
1807+
calloc_mem = scope_calloc(nmemb, size);
1808+
return calloc_mem;
1809+
}
1810+
1811+
WRAP_CHECK(calloc, NULL);
1812+
1813+
void *ptr = g_fn.calloc(nmemb, size);
1814+
if(g_log) {
1815+
if (call_backtrace)
1816+
scopeBacktraceTest();
1817+
size_t allocated_size = g_fn.malloc_usable_size(ptr);
1818+
no_bytes_allocated += allocated_size;
1819+
1820+
scopeLogError("function = %s allocate: %zu bytes, requested %zu bytes. Total allocated size %zu bytes\n", __FUNCTION__, allocated_size, size*nmemb, no_bytes_allocated);
1821+
}
1822+
1823+
return ptr;
1824+
}
1825+
1826+
EXPORTON void *
1827+
realloc(void *ptr, size_t size) {
1828+
WRAP_CHECK(realloc, NULL);
1829+
1830+
void *new_ptr = g_fn.realloc(ptr, size);
1831+
1832+
if(g_log) {
1833+
if (call_backtrace)
1834+
scopeBacktraceTest();
1835+
size_t prev_size = g_fn.malloc_usable_size(ptr);
1836+
no_bytes_allocated -= prev_size;
1837+
1838+
size_t new_size = g_fn.malloc_usable_size(new_ptr);
1839+
no_bytes_allocated += new_size;
1840+
1841+
scopeLogError("function = %s reallocate: from %zu to %zu bytes, requested %zu bytes. Total allocated size %zu bytes\n", __FUNCTION__, prev_size, new_size, size, no_bytes_allocated);
1842+
}
1843+
1844+
return new_ptr;
1845+
}
1846+
1847+
EXPORTON void
1848+
free(void *ptr) {
1849+
WRAP_CHECK_VOID(free);
1850+
1851+
if(ptr) {
1852+
if(g_log) {
1853+
if (call_backtrace)
1854+
scopeBacktraceTest();
1855+
size_t freed_size = g_fn.malloc_usable_size(ptr);
1856+
no_bytes_allocated -= freed_size;
1857+
1858+
scopeLogError("function = %s freeing: %zu bytes. Total allocated size %zu bytes\n", __FUNCTION__, freed_size, no_bytes_allocated);
1859+
}
1860+
}
1861+
if (ptr == calloc_mem) {
1862+
scopeLogError("calloc_mem\n");
1863+
scope_free(calloc_mem);
1864+
} else {
1865+
g_fn.free(ptr);
1866+
}
1867+
}
1868+
1869+
EXPORTON void *
1870+
mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
1871+
{
1872+
WRAP_CHECK(mmap, NULL);
1873+
void * ptr = g_fn.mmap(addr, length, prot, flags, fd, offset);
1874+
1875+
if (ptr != MAP_FAILED) {
1876+
// no_bytes_allocated += length;
1877+
scopeLogError("function = %s map: %zu bytes ", __FUNCTION__, length);
1878+
// scopeLogError("Total allocated size: %zu bytes", no_bytes_allocated);
1879+
}
1880+
1881+
return ptr;
1882+
}
1883+
1884+
EXPORTON int
1885+
munmap(void *addr, size_t length)
1886+
{
1887+
WRAP_CHECK(munmap, -1);
1888+
1889+
int res = g_fn.munmap(addr, length);
1890+
1891+
if (!res) {
1892+
// no_bytes_allocated -= length;
1893+
scopeLogError("function = %s unmap: %zu bytes ", __FUNCTION__, length);
1894+
// scopeLogError("Total allocated size: %zu bytes", no_bytes_allocated);
1895+
}
1896+
1897+
return res;
1898+
}
1899+
17281900
EXPORTON int
17291901
open(const char *pathname, int flags, ...)
17301902
{

0 commit comments

Comments
 (0)