220 lines
6.4 KiB
C
220 lines
6.4 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include <Eina.h>
|
|
|
|
static char *
|
|
pstr(const char *cmd, int lines)
|
|
{
|
|
FILE *f;
|
|
char *str = NULL;
|
|
char buf[4096];
|
|
int str_len = 0;
|
|
int n = 0;
|
|
int count = 0;
|
|
|
|
f = popen(cmd, "r");
|
|
if (!f) return NULL;
|
|
while (fgets(buf, sizeof(buf) - 1, f))
|
|
{
|
|
int len = strlen(buf);
|
|
if ((len > 1) && (buf[len - 1] == '\n'))
|
|
{
|
|
buf[len - 1] = 0;
|
|
len--;
|
|
}
|
|
str_len += len;
|
|
str = realloc(str, str_len + 1);
|
|
if (count == 0) str[0] = 0;
|
|
strcat(str, buf);
|
|
n++;
|
|
count++;
|
|
if (n >= lines) break;
|
|
}
|
|
pclose(f);
|
|
return str;
|
|
}
|
|
|
|
static char *
|
|
addr2func(const char *file, const char *addr)
|
|
{
|
|
char *s;
|
|
char cmd[4096], buf[4096];
|
|
static Eina_Hash *hash = NULL;
|
|
|
|
if (!hash) hash = eina_hash_string_superfast_new(NULL);
|
|
snprintf(buf, sizeof(buf), "%s %s", file, addr);
|
|
s = eina_hash_find(hash, buf);
|
|
if (s) return strdup(s);
|
|
snprintf(cmd, sizeof(cmd), "addr2line -f -e %s", buf);
|
|
s = pstr(cmd, 1);
|
|
eina_hash_add(hash, buf, s);
|
|
return strdup(s);
|
|
}
|
|
|
|
static FILE *outf = NULL;
|
|
|
|
#define OUT(fmt, args...) fprintf(outf, fmt, ##args)
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
FILE *f;
|
|
char buf[4096];
|
|
int items = 0;
|
|
int btnum = 0;
|
|
int expected = 0;
|
|
time_t t0;
|
|
|
|
if (argc < 3)
|
|
{
|
|
printf("usage: mtdump MTLOGFILE OUTFILE\n");
|
|
exit(1);
|
|
}
|
|
|
|
f = fopen(argv[1], "r");
|
|
if (!f)
|
|
{
|
|
perror("fopen");
|
|
exit(1);
|
|
}
|
|
|
|
outf = fopen(argv[2], "w");
|
|
if (!outf)
|
|
{
|
|
perror("fopen");
|
|
exit(1);
|
|
}
|
|
|
|
while (fgets(buf, sizeof(buf) - 1, f))
|
|
{
|
|
if (!strncmp(buf, "== ", 3)) expected++;
|
|
}
|
|
fseek(f, 0, SEEK_SET);
|
|
t0 = time(NULL);
|
|
while (fgets(buf, sizeof(buf) - 1, f))
|
|
{
|
|
int len;
|
|
|
|
len = strlen(buf);
|
|
if (len < 2) continue;
|
|
if ((len > 1) && (buf[len - 1] == '\n'))
|
|
{
|
|
buf[len - 1] = 0;
|
|
len--;
|
|
}
|
|
if (!strncmp(buf, "== ", 3))
|
|
{
|
|
unsigned long size;
|
|
char type[4096] = "";
|
|
unsigned long alloctime;
|
|
|
|
if (sscanf(buf, "%*s %s %lu %*s %lu", type, &size, &alloctime)
|
|
== 3)
|
|
{
|
|
time_t t;
|
|
struct tm *tmp;
|
|
char out[256] = "??";
|
|
int eta;
|
|
|
|
if (items > 0) OUT("\n");
|
|
items++;
|
|
t = time(NULL) - t0;
|
|
eta = (expected * (int)t) / items;
|
|
printf("%i/%i -- ETA %i min %i sec \r",
|
|
items, expected, eta / 60, eta % 60);
|
|
fflush(stdout);
|
|
btnum = 0;
|
|
t = alloctime;
|
|
tmp = localtime(&t);
|
|
if (tmp)
|
|
strftime(out, sizeof(out), "%F/%T", tmp);
|
|
else
|
|
strcpy(out, "??");
|
|
OUT("%lu %s %s |", size, type, out);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (btnum > 0)
|
|
{
|
|
if (strchr(buf, '['))
|
|
{
|
|
// 1 of:
|
|
// /usr/local/lib/libeina.so.1(+0x16ab8)[0x7fdaccc4cab8]
|
|
// /lib/x86_64-linux-gnu/libc.so.6(__strdup+0x22)[0x7fdace0732f2]
|
|
// ello[0x402d8c]
|
|
// /usr/local/bin/ello[0x402d8c]
|
|
if (strchr(buf, '('))
|
|
{
|
|
char file[4096], addr[4096];
|
|
// 1 of:
|
|
// /usr/local/lib/libeina.so.1(+0x16ab8)[0x7fdaccc4cab8]
|
|
// /lib/x86_64-linux-gnu/libc.so.6(__strdup+0x22)[0x7fdace0732f2]
|
|
if (sscanf(buf, "%[^(](%[^)])%*s", file, addr) == 2)
|
|
{
|
|
if (addr[0] == '+')
|
|
{
|
|
char *s = addr2func(file, addr + 1);
|
|
if (s)
|
|
{
|
|
OUT(" %s", s);
|
|
free(s);
|
|
}
|
|
else
|
|
OUT(" ??");
|
|
}
|
|
else
|
|
{
|
|
char *s;
|
|
|
|
s = strchr(addr, '+');
|
|
if (s) *s = 0;
|
|
OUT(" %s", addr);
|
|
}
|
|
}
|
|
else
|
|
OUT(" ??");
|
|
}
|
|
else
|
|
{
|
|
// 1 of:
|
|
// ello[0x402d8c]
|
|
// /usr/local/bin/ello[0x402d8c]
|
|
if (buf[0] == '/')
|
|
{
|
|
char file[4096], addr[4096];
|
|
|
|
if (sscanf(buf, "%[^\\[][%[^]]]", file, addr) == 2)
|
|
{
|
|
char *s = addr2func(file, addr);
|
|
if (s)
|
|
{
|
|
OUT(" %s", s);
|
|
free(s);
|
|
}
|
|
else
|
|
OUT(" ??");
|
|
}
|
|
else
|
|
OUT(" ??");
|
|
}
|
|
else
|
|
OUT(" ?main?");
|
|
}
|
|
}
|
|
else
|
|
OUT(" ??");
|
|
}
|
|
btnum++;
|
|
}
|
|
}
|
|
fclose(f);
|
|
fclose(outf);
|
|
|
|
exit(0);
|
|
return 0;
|
|
}
|