Default off, activated by --dev-performance, and always on in c4w.
Török Edvin authored on 2011/02/15 02:19:20... | ... |
@@ -383,6 +383,9 @@ |
383 | 383 |
/* Define to 1 if you have the <sys/stat.h> header file. */ |
384 | 384 |
#undef HAVE_SYS_STAT_H |
385 | 385 |
|
386 |
+/* Define to 1 if you have the <sys/times.h> header file. */ |
|
387 |
+#undef HAVE_SYS_TIMES_H |
|
388 |
+ |
|
386 | 389 |
/* Define to 1 if you have the <sys/types.h> header file. */ |
387 | 390 |
#undef HAVE_SYS_TYPES_H |
388 | 391 |
|
... | ... |
@@ -630,6 +630,9 @@ int scanmanager(const struct optstruct *opts) |
630 | 630 |
options |= CL_SCAN_INTERNAL_COLLECT_SHA; |
631 | 631 |
#endif |
632 | 632 |
|
633 |
+ if(optget(opts, "dev-performance")->enabled) |
|
634 |
+ options |= CL_SCAN_PERFORMANCE_INFO; |
|
635 |
+ |
|
633 | 636 |
if(optget(opts, "detect-structured")->enabled) { |
634 | 637 |
options |= CL_SCAN_STRUCTURED; |
635 | 638 |
|
... | ... |
@@ -13341,7 +13341,7 @@ GPERF=${GPERF-"${am_missing_run}gperf"} |
13341 | 13341 |
|
13342 | 13342 |
|
13343 | 13343 |
|
13344 |
-for ac_header in stdint.h unistd.h sys/int_types.h dlfcn.h inttypes.h sys/inttypes.h memory.h ndir.h stdlib.h strings.h string.h sys/mman.h sys/param.h sys/stat.h sys/types.h malloc.h poll.h limits.h sys/filio.h sys/uio.h termios.h stdbool.h pwd.h grp.h |
|
13344 |
+for ac_header in stdint.h unistd.h sys/int_types.h dlfcn.h inttypes.h sys/inttypes.h sys/times.h memory.h ndir.h stdlib.h strings.h string.h sys/mman.h sys/param.h sys/stat.h sys/types.h malloc.h poll.h limits.h sys/filio.h sys/uio.h termios.h stdbool.h pwd.h grp.h |
|
13345 | 13345 |
do : |
13346 | 13346 |
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` |
13347 | 13347 |
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" |
... | ... |
@@ -408,7 +408,7 @@ AM_CONDITIONAL([VERSIONSCRIPT], test "x$ac_cv_ld_version_script" = "xyes") |
408 | 408 |
AM_MISSING_PROG(GPERF, gperf) |
409 | 409 |
AC_SUBST(GPERF) |
410 | 410 |
|
411 |
-AC_CHECK_HEADERS([stdint.h unistd.h sys/int_types.h dlfcn.h inttypes.h sys/inttypes.h memory.h ndir.h stdlib.h strings.h string.h sys/mman.h sys/param.h sys/stat.h sys/types.h malloc.h poll.h limits.h sys/filio.h sys/uio.h termios.h stdbool.h pwd.h grp.h]) |
|
411 |
+AC_CHECK_HEADERS([stdint.h unistd.h sys/int_types.h dlfcn.h inttypes.h sys/inttypes.h sys/times.h memory.h ndir.h stdlib.h strings.h string.h sys/mman.h sys/param.h sys/stat.h sys/types.h malloc.h poll.h limits.h sys/filio.h sys/uio.h termios.h stdbool.h pwd.h grp.h]) |
|
412 | 412 |
AC_CHECK_HEADER([syslog.h],AC_DEFINE([USE_SYSLOG],1,[use syslog]),) |
413 | 413 |
|
414 | 414 |
AC_TYPE_OFF_T |
... | ... |
@@ -68,7 +68,7 @@ target_triplet = @target@ |
68 | 68 |
|
69 | 69 |
subdir = libclamav |
70 | 70 |
DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \ |
71 |
- $(srcdir)/Makefile.in |
|
71 |
+ $(srcdir)/Makefile.in COPYING |
|
72 | 72 |
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 |
73 | 73 |
am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ |
74 | 74 |
$(top_srcdir)/m4/argz.m4 \ |
... | ... |
@@ -1624,6 +1624,8 @@ int cli_bytecode_run(const struct cli_all_bc *bcs, const struct cli_bc *bc, stru |
1624 | 1624 |
cli_dbgmsg("bytecode triggered but running bytecodes is disabled\n"); |
1625 | 1625 |
return CL_SUCCESS; |
1626 | 1626 |
} |
1627 |
+ if (cctx) |
|
1628 |
+ cli_event_time_start(cctx->perf, PERFT_BYTECODE); |
|
1627 | 1629 |
ctx->env = &bcs->env; |
1628 | 1630 |
context_safe(ctx); |
1629 | 1631 |
if (test_mode) { |
... | ... |
@@ -1736,6 +1738,8 @@ int cli_bytecode_run(const struct cli_all_bc *bcs, const struct cli_bc *bc, stru |
1736 | 1736 |
} |
1737 | 1737 |
cli_events_free(jit_ev); |
1738 | 1738 |
cli_events_free(interp_ev); |
1739 |
+ if (cctx) |
|
1740 |
+ cli_event_time_stop(cctx->perf, PERFT_BYTECODE); |
|
1739 | 1741 |
return ret; |
1740 | 1742 |
} |
1741 | 1743 |
|
... | ... |
@@ -119,6 +119,7 @@ typedef enum { |
119 | 119 |
#define CL_SCAN_HEURISTIC_PRECEDENCE 0x80000 |
120 | 120 |
#define CL_SCAN_BLOCKMACROS 0x100000 |
121 | 121 |
|
122 |
+#define CL_SCAN_PERFORMANCE_INFO 0x40000000 /* collect performance timings */ |
|
122 | 123 |
#define CL_SCAN_INTERNAL_COLLECT_SHA 0x80000000 /* Enables hash output in sha-collect builds - for internal use only */ |
123 | 124 |
|
124 | 125 |
/* recommended scan settings */ |
... | ... |
@@ -150,8 +150,10 @@ void cli_event_int(cli_events_t *ctx, unsigned id, uint64_t arg) |
150 | 150 |
switch (ev->multiple) { |
151 | 151 |
case multiple_last: |
152 | 152 |
ev->u.v_int = arg; |
153 |
+ ev->count++; |
|
153 | 154 |
break; |
154 | 155 |
case multiple_sum: |
156 |
+ ev->count++; |
|
155 | 157 |
ev->u.v_int += arg; |
156 | 158 |
break; |
157 | 159 |
case multiple_chain: |
... | ... |
@@ -176,6 +178,24 @@ void cli_event_time_start(cli_events_t *ctx, unsigned id) |
176 | 176 |
} |
177 | 177 |
gettimeofday(&tv, NULL); |
178 | 178 |
ev->u.v_int -= ((int64_t)tv.tv_sec * 1000000) + tv.tv_usec; |
179 |
+ ev->count++; |
|
180 |
+} |
|
181 |
+ |
|
182 |
+void cli_event_time_nested_start(cli_events_t *ctx, unsigned id, unsigned nestedid) |
|
183 |
+{ |
|
184 |
+ struct timeval tv; |
|
185 |
+ struct cli_event *ev = get_event(ctx, id); |
|
186 |
+ struct cli_event *evnested = get_event(ctx, nestedid); |
|
187 |
+ if (!ev || !evnested) |
|
188 |
+ return; |
|
189 |
+ if (ev->type != ev_time || evnested->type != ev_time) { |
|
190 |
+ cli_event_error_str(ctx, "cli_event_time* must be called with ev_time type"); |
|
191 |
+ return; |
|
192 |
+ } |
|
193 |
+ gettimeofday(&tv, NULL); |
|
194 |
+ ev->u.v_int -= ((int64_t)tv.tv_sec * 1000000) + tv.tv_usec; |
|
195 |
+ ev->u.v_int += evnested->u.v_int; |
|
196 |
+ ev->count++; |
|
179 | 197 |
} |
180 | 198 |
|
181 | 199 |
void cli_event_time_stop(cli_events_t *ctx, unsigned id) |
... | ... |
@@ -192,6 +212,22 @@ void cli_event_time_stop(cli_events_t *ctx, unsigned id) |
192 | 192 |
ev->u.v_int += ((int64_t)tv.tv_sec * 1000000) + tv.tv_usec; |
193 | 193 |
} |
194 | 194 |
|
195 |
+void cli_event_time_nested_stop(cli_events_t *ctx, unsigned id, unsigned nestedid) |
|
196 |
+{ |
|
197 |
+ struct timeval tv; |
|
198 |
+ struct cli_event *ev = get_event(ctx, id); |
|
199 |
+ struct cli_event *evnested = get_event(ctx, nestedid); |
|
200 |
+ if (!ev || !evnested) |
|
201 |
+ return; |
|
202 |
+ if (ev->type != ev_time || evnested->type != ev_time) { |
|
203 |
+ cli_event_error_str(ctx, "cli_event_time* must be called with ev_time type"); |
|
204 |
+ return; |
|
205 |
+ } |
|
206 |
+ gettimeofday(&tv, NULL); |
|
207 |
+ ev->u.v_int += ((int64_t)tv.tv_sec * 1000000) + tv.tv_usec; |
|
208 |
+ ev->u.v_int -= evnested->u.v_int; |
|
209 |
+} |
|
210 |
+ |
|
195 | 211 |
static void event_string(cli_events_t *ctx, struct cli_event *ev, const char *str) |
196 | 212 |
{ |
197 | 213 |
if (!str) |
... | ... |
@@ -74,7 +74,8 @@ void cli_event_data(cli_events_t *ctx, unsigned id, const void* data, uint32_t l |
74 | 74 |
void cli_event_fastdata(cli_events_t *ctx, unsigned id, const void *data, uint32_t len); |
75 | 75 |
|
76 | 76 |
void cli_event_time_start(cli_events_t *ctx, unsigned id); |
77 |
-void cli_event_time_stop(cli_events_t *ctx, unsigned id); |
|
77 |
+void cli_event_time_nested_start(cli_events_t *ctx, unsigned id, unsigned nestedid); |
|
78 |
+void cli_event_time_nested_stop(cli_events_t *ctx, unsigned id, unsigned nestedid); |
|
78 | 79 |
|
79 | 80 |
/* event_count is implemented as ev_int, with ev_multiple_sum multiple */ |
80 | 81 |
void cli_event_count(cli_events_t *ctx, unsigned id); |
... | ... |
@@ -99,4 +100,22 @@ int cli_event_diff_all(cli_events_t *ctx1, cli_events_t *ctx2, compare_filter_t |
99 | 99 |
/* returns whether the given context had errors */ |
100 | 100 |
int cli_event_errors(cli_events_t *ctx); |
101 | 101 |
|
102 |
+enum perfev { |
|
103 |
+ PERFT_SCAN, |
|
104 |
+ PERFT_PRECB, |
|
105 |
+ PERFT_POSTCB, |
|
106 |
+ PERFT_CACHE, |
|
107 |
+ PERFT_FT, |
|
108 |
+ PERFT_CONTAINER, |
|
109 |
+ PERFT_SCRIPT, |
|
110 |
+ PERFT_PE, |
|
111 |
+ PERFT_RAW, |
|
112 |
+ PERFT_RAWTYPENO, |
|
113 |
+ PERFT_MAP, |
|
114 |
+ PERFT_BYTECODE, |
|
115 |
+ PERFT_KTIME, |
|
116 |
+ PERFT_UTIME, |
|
117 |
+ PERFT_LAST |
|
118 |
+}; |
|
119 |
+ |
|
102 | 120 |
#endif |
... | ... |
@@ -43,6 +43,7 @@ |
43 | 43 |
#include "regex/regex.h" |
44 | 44 |
#include "bytecode.h" |
45 | 45 |
#include "bytecode_api.h" |
46 |
+#include "events.h" |
|
46 | 47 |
|
47 | 48 |
/* |
48 | 49 |
* CL_FLEVEL is the signature f-level specific to the current code and |
... | ... |
@@ -125,6 +126,7 @@ typedef struct cli_ctx_tag { |
125 | 125 |
fmap_t **fmap; |
126 | 126 |
bitset_t* hook_lsig_matches; |
127 | 127 |
void *cb_ctx; |
128 |
+ cli_events_t* perf; |
|
128 | 129 |
#ifdef HAVE__INTERNAL__SHA_COLLECT |
129 | 130 |
char entry_filename[2048]; |
130 | 131 |
int sha_collect; |
... | ... |
@@ -39,6 +39,9 @@ |
39 | 39 |
#endif |
40 | 40 |
#include <fcntl.h> |
41 | 41 |
#include <dirent.h> |
42 |
+#ifdef HAVE_SYS_TIMES_H |
|
43 |
+#include <sys/times.h> |
|
44 |
+#endif |
|
42 | 45 |
|
43 | 46 |
#define DCONF_ARCH ctx->dconf->archive |
44 | 47 |
#define DCONF_DOC ctx->dconf->doc |
... | ... |
@@ -1723,6 +1726,150 @@ static int cli_scanembpe(cli_ctx *ctx, off_t offset) |
1723 | 1723 |
return CL_CLEAN; |
1724 | 1724 |
} |
1725 | 1725 |
|
1726 |
+ |
|
1727 |
+#if defined(_WIN32) || defined(C_LINUX) |
|
1728 |
+#define PERF_MEASURE |
|
1729 |
+#endif |
|
1730 |
+ |
|
1731 |
+#ifdef PERF_MEASURE |
|
1732 |
+ |
|
1733 |
+static struct { |
|
1734 |
+ enum perfev id; |
|
1735 |
+ const char *name; |
|
1736 |
+ enum ev_type type; |
|
1737 |
+} perf_events[] = { |
|
1738 |
+ {PERFT_SCAN, "full scan", ev_time}, |
|
1739 |
+ {PERFT_PRECB, "prescan cb", ev_time}, |
|
1740 |
+ {PERFT_POSTCB, "postscan cb", ev_time}, |
|
1741 |
+ {PERFT_CACHE, "cache", ev_time}, |
|
1742 |
+ {PERFT_FT, "filetype", ev_time}, |
|
1743 |
+ {PERFT_CONTAINER, "container", ev_time}, |
|
1744 |
+ {PERFT_SCRIPT, "script", ev_time}, |
|
1745 |
+ {PERFT_PE, "pe", ev_time}, |
|
1746 |
+ {PERFT_RAW, "raw", ev_time}, |
|
1747 |
+ {PERFT_RAWTYPENO, "raw container", ev_time}, |
|
1748 |
+ {PERFT_MAP, "map", ev_time}, |
|
1749 |
+ {PERFT_BYTECODE,"bytecode", ev_time}, |
|
1750 |
+ {PERFT_KTIME,"kernel", ev_int}, |
|
1751 |
+ {PERFT_UTIME,"user", ev_int} |
|
1752 |
+}; |
|
1753 |
+ |
|
1754 |
+static void get_thread_times(uint64_t *kt, uint64_t *ut) |
|
1755 |
+{ |
|
1756 |
+#ifdef _WIN32 |
|
1757 |
+ LPFILETIME c,e,k,u; |
|
1758 |
+ ULARGE_INTEGER kl,ul; |
|
1759 |
+ if (!GetThreadTimes(GetCurrentThread(), &c, &e, &k, &u)) { |
|
1760 |
+ *kt = *ut = 0; |
|
1761 |
+ return; |
|
1762 |
+ } |
|
1763 |
+ kl.LowPart = k.dwLowDateTime; |
|
1764 |
+ kl.HighPart = k.dwHighDateTime; |
|
1765 |
+ ul.LowPart = u.dwLowDateTime; |
|
1766 |
+ ul.HighPart = u.dwHighDateTime; |
|
1767 |
+ *kt = kl.QuadPart / 10; |
|
1768 |
+ *ut = ul.QuadPart / 10; |
|
1769 |
+#else |
|
1770 |
+ struct tms tbuf; |
|
1771 |
+ if (times(&tbuf) != -1) { |
|
1772 |
+ clock_t tck = sysconf(_SC_CLK_TCK); |
|
1773 |
+ *kt = 1000000*tbuf.tms_stime / tck; |
|
1774 |
+ *ut = 1000000*tbuf.tms_utime / tck; |
|
1775 |
+ } else { |
|
1776 |
+ *kt = *ut = 0; |
|
1777 |
+ } |
|
1778 |
+#endif |
|
1779 |
+} |
|
1780 |
+ |
|
1781 |
+static inline void perf_init(cli_ctx *ctx) |
|
1782 |
+{ |
|
1783 |
+ uint64_t kt,ut; |
|
1784 |
+ unsigned i; |
|
1785 |
+ |
|
1786 |
+ if (!(ctx->options & CL_SCAN_PERFORMANCE_INFO)) |
|
1787 |
+ return; |
|
1788 |
+ |
|
1789 |
+ ctx->perf = cli_events_new(PERFT_LAST); |
|
1790 |
+ for (i=0;i<sizeof(perf_events)/sizeof(perf_events[0]);i++) { |
|
1791 |
+ if (cli_event_define(ctx->perf, perf_events[i].id, perf_events[i].name, |
|
1792 |
+ perf_events[i].type, multiple_sum) == -1) |
|
1793 |
+ continue; |
|
1794 |
+ } |
|
1795 |
+ cli_event_time_start(ctx->perf, PERFT_SCAN); |
|
1796 |
+ get_thread_times(&kt, &ut); |
|
1797 |
+ cli_event_int(ctx->perf, PERFT_KTIME, -kt); |
|
1798 |
+ cli_event_int(ctx->perf, PERFT_UTIME, -ut); |
|
1799 |
+} |
|
1800 |
+ |
|
1801 |
+static inline void perf_done(cli_ctx* ctx) |
|
1802 |
+{ |
|
1803 |
+ char timestr[512]; |
|
1804 |
+ char *p; |
|
1805 |
+ unsigned i; |
|
1806 |
+ uint64_t kt,ut; |
|
1807 |
+ cli_events_t *perf = ctx->perf; |
|
1808 |
+ |
|
1809 |
+ if (!perf) |
|
1810 |
+ return; |
|
1811 |
+ |
|
1812 |
+ p = timestr; |
|
1813 |
+ char *pend = timestr + sizeof(timestr) - 1; |
|
1814 |
+ *pend = 0; |
|
1815 |
+ |
|
1816 |
+ cli_event_time_stop(perf, PERFT_SCAN); |
|
1817 |
+ get_thread_times(&kt, &ut); |
|
1818 |
+ cli_event_int(perf, PERFT_KTIME, kt); |
|
1819 |
+ cli_event_int(perf, PERFT_UTIME, ut); |
|
1820 |
+ |
|
1821 |
+ for (i=0;i<sizeof(perf_events)/sizeof(perf_events[0]);i++) { |
|
1822 |
+ union ev_val val; |
|
1823 |
+ unsigned count; |
|
1824 |
+ |
|
1825 |
+ cli_event_get(perf, perf_events[i].id, &val, &count); |
|
1826 |
+ if (p < pend) |
|
1827 |
+ p += snprintf(p, pend - p, "%s: %d.%03ums, ", perf_events[i].name, |
|
1828 |
+ (signed)(val.v_int / 1000), |
|
1829 |
+ (unsigned)(val.v_int % 1000)); |
|
1830 |
+ } |
|
1831 |
+ *p = 0; |
|
1832 |
+ cli_infomsg(ctx, "performance: %s\n", timestr); |
|
1833 |
+ |
|
1834 |
+ |
|
1835 |
+ cli_events_free(perf); |
|
1836 |
+ ctx->perf = NULL; |
|
1837 |
+} |
|
1838 |
+ |
|
1839 |
+static inline void perf_start(cli_ctx* ctx, int id) |
|
1840 |
+{ |
|
1841 |
+ cli_event_time_start(ctx->perf, id); |
|
1842 |
+} |
|
1843 |
+ |
|
1844 |
+static inline void perf_stop(cli_ctx* ctx, int id) |
|
1845 |
+{ |
|
1846 |
+ cli_event_time_stop(ctx->perf, id); |
|
1847 |
+} |
|
1848 |
+ |
|
1849 |
+static inline void perf_nested_start(cli_ctx* ctx, int id, int nestedid) |
|
1850 |
+{ |
|
1851 |
+ cli_event_time_nested_start(ctx->perf, id, nestedid); |
|
1852 |
+} |
|
1853 |
+ |
|
1854 |
+static inline void perf_nested_stop(cli_ctx* ctx, int id, int nestedid) |
|
1855 |
+{ |
|
1856 |
+ cli_event_time_nested_stop(ctx->perf, id, nestedid); |
|
1857 |
+} |
|
1858 |
+ |
|
1859 |
+ |
|
1860 |
+#else |
|
1861 |
+static inline void perf_init(cli_events_t **perf) {} |
|
1862 |
+static inline void perf_start(cli_ctx* ctx, int id){} |
|
1863 |
+static inline void perf_stop(cli_ctx* ctx, int id){} |
|
1864 |
+static inline void perf_nested_start(cli_ctx* ctx, int id){} |
|
1865 |
+static inline void perf_nested_stop(cli_ctx* ctx, int id){} |
|
1866 |
+static inline void perf_done(cli_events_t **perf) {} |
|
1867 |
+#endif |
|
1868 |
+ |
|
1869 |
+ |
|
1726 | 1870 |
static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_t *dettype, unsigned char *refhash) |
1727 | 1871 |
{ |
1728 | 1872 |
int ret = CL_CLEAN, nret = CL_CLEAN; |
... | ... |
@@ -1738,12 +1885,15 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
1738 | 1738 |
if(ctx->engine->maxreclevel && ctx->recursion >= ctx->engine->maxreclevel) |
1739 | 1739 |
return CL_EMAXREC; |
1740 | 1740 |
|
1741 |
+ perf_start(ctx, PERFT_RAW); |
|
1741 | 1742 |
if(typercg) |
1742 | 1743 |
acmode |= AC_SCAN_FT; |
1743 | 1744 |
|
1744 | 1745 |
ret = cli_fmap_scandesc(ctx, type == CL_TYPE_TEXT_ASCII ? 0 : type, 0, &ftoffset, acmode, NULL, refhash); |
1746 |
+ perf_stop(ctx, PERFT_RAW); |
|
1745 | 1747 |
|
1746 | 1748 |
if(ret >= CL_TYPENO) { |
1749 |
+ perf_nested_start(ctx, PERFT_RAWTYPENO, PERFT_SCAN); |
|
1747 | 1750 |
ctx->recursion++; |
1748 | 1751 |
if(nret != CL_VIRUS) { |
1749 | 1752 |
lastzip = lastrar = 0xdeadbeef; |
... | ... |
@@ -1880,6 +2030,7 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
1880 | 1880 |
default: |
1881 | 1881 |
break; |
1882 | 1882 |
} |
1883 |
+ perf_nested_stop(ctx, PERFT_RAWTYPENO, PERFT_SCAN); |
|
1883 | 1884 |
ctx->recursion--; |
1884 | 1885 |
ret = nret; |
1885 | 1886 |
} |
... | ... |
@@ -1915,20 +2066,24 @@ static void emax_reached(cli_ctx *ctx) { |
1915 | 1915 |
#define ret_from_magicscan(retcode) do { \ |
1916 | 1916 |
cli_dbgmsg("cli_magic_scandesc: returning %d %s\n", retcode, __AT__); \ |
1917 | 1917 |
if(ctx->engine->cb_post_scan) { \ |
1918 |
+ perf_start(ctx, PERFT_POSTCB); \ |
|
1918 | 1919 |
switch(ctx->engine->cb_post_scan(desc, retcode, retcode == CL_VIRUS && ctx->virname ? *ctx->virname : NULL, ctx->cb_ctx)) { \ |
1919 | 1920 |
case CL_BREAK: \ |
1920 | 1921 |
cli_dbgmsg("cli_magic_scandesc: file whitelisted by callback\n"); \ |
1922 |
+ perf_stop(ctx, PERFT_POSTCB); \ |
|
1921 | 1923 |
return CL_CLEAN; \ |
1922 | 1924 |
case CL_VIRUS: \ |
1923 | 1925 |
cli_dbgmsg("cli_magic_scandesc: file blacklisted by callback\n"); \ |
1924 | 1926 |
if(ctx->virname) \ |
1925 | 1927 |
*ctx->virname = "Detected.By.Callback"; \ |
1928 |
+ perf_stop(ctx, PERFT_POSTCB); \ |
|
1926 | 1929 |
return CL_VIRUS; \ |
1927 | 1930 |
case CL_CLEAN: \ |
1928 | 1931 |
break; \ |
1929 | 1932 |
default: \ |
1930 | 1933 |
cli_warnmsg("cli_magic_scandesc: ignoring bad return code from callback\n"); \ |
1931 | 1934 |
} \ |
1935 |
+ perf_stop(ctx, PERFT_POSTCB); \ |
|
1932 | 1936 |
}\ |
1933 | 1937 |
return retcode; \ |
1934 | 1938 |
} while(0) |
... | ... |
@@ -1981,18 +2136,23 @@ static int magic_scandesc(int desc, cli_ctx *ctx, cli_file_t type) |
1981 | 1981 |
} |
1982 | 1982 |
|
1983 | 1983 |
ctx->fmap++; |
1984 |
+ perf_start(ctx, PERFT_MAP); |
|
1984 | 1985 |
if(!(*ctx->fmap = fmap(desc, 0, sb.st_size))) { |
1985 | 1986 |
cli_errmsg("CRITICAL: fmap() failed\n"); |
1986 | 1987 |
ctx->fmap--; |
1988 |
+ perf_stop(ctx, PERFT_MAP); |
|
1987 | 1989 |
ret_from_magicscan(CL_EMEM); |
1988 | 1990 |
} |
1991 |
+ perf_stop(ctx, PERFT_MAP); |
|
1989 | 1992 |
|
1990 | 1993 |
if(ctx->engine->cb_pre_scan) { |
1994 |
+ perf_start(ctx, PERFT_PRECB); |
|
1991 | 1995 |
switch(ctx->engine->cb_pre_scan(desc, ctx->cb_ctx)) { |
1992 | 1996 |
case CL_BREAK: |
1993 | 1997 |
cli_dbgmsg("cli_magic_scandesc: file whitelisted by callback\n"); |
1994 | 1998 |
funmap(*ctx->fmap); |
1995 | 1999 |
ctx->fmap--; |
2000 |
+ perf_stop(ctx, PERFT_PRECB); |
|
1996 | 2001 |
ret_from_magicscan(CL_CLEAN); |
1997 | 2002 |
case CL_VIRUS: |
1998 | 2003 |
cli_dbgmsg("cli_magic_scandesc: file blacklisted by callback\n"); |
... | ... |
@@ -2000,19 +2160,24 @@ static int magic_scandesc(int desc, cli_ctx *ctx, cli_file_t type) |
2000 | 2000 |
*ctx->virname = "Detected.By.Callback"; |
2001 | 2001 |
funmap(*ctx->fmap); |
2002 | 2002 |
ctx->fmap--; |
2003 |
+ perf_stop(ctx, PERFT_PRECB); |
|
2003 | 2004 |
ret_from_magicscan(CL_VIRUS); |
2004 | 2005 |
case CL_CLEAN: |
2005 | 2006 |
break; |
2006 | 2007 |
default: |
2007 | 2008 |
cli_warnmsg("cli_magic_scandesc: ignoring bad return code from callback\n"); |
2008 | 2009 |
} |
2010 |
+ perf_stop(ctx, PERFT_PRECB); |
|
2009 | 2011 |
} |
2010 | 2012 |
|
2013 |
+ perf_start(ctx, PERFT_CACHE); |
|
2011 | 2014 |
if(cache_check(hash, ctx) == CL_CLEAN) { |
2012 | 2015 |
funmap(*ctx->fmap); |
2013 | 2016 |
ctx->fmap--; |
2017 |
+ perf_stop(ctx, PERFT_CACHE); |
|
2014 | 2018 |
ret_from_magicscan(CL_CLEAN); |
2015 | 2019 |
} |
2020 |
+ perf_stop(ctx, PERFT_CACHE); |
|
2016 | 2021 |
hashed_size = (*ctx->fmap)->len; |
2017 | 2022 |
old_hook_lsig_matches = ctx->hook_lsig_matches; |
2018 | 2023 |
ctx->hook_lsig_matches = NULL; |
... | ... |
@@ -2038,8 +2203,10 @@ static int magic_scandesc(int desc, cli_ctx *ctx, cli_file_t type) |
2038 | 2038 |
ret_from_magicscan(ret); |
2039 | 2039 |
} |
2040 | 2040 |
|
2041 |
+ perf_start(ctx, PERFT_FT); |
|
2041 | 2042 |
if(type == CL_TYPE_ANY) |
2042 | 2043 |
type = cli_filetype2(*ctx->fmap, ctx->engine); /* FIXMEFMAP: port to fmap */ |
2044 |
+ perf_stop(ctx, PERFT_FT); |
|
2043 | 2045 |
if(type == CL_TYPE_ERROR) { |
2044 | 2046 |
cli_dbgmsg("cli_magic_scandesc: cli_filetype2 returned CL_TYPE_ERROR\n"); |
2045 | 2047 |
funmap(*ctx->fmap); |
... | ... |
@@ -2073,6 +2240,7 @@ static int magic_scandesc(int desc, cli_ctx *ctx, cli_file_t type) |
2073 | 2073 |
} |
2074 | 2074 |
|
2075 | 2075 |
ctx->recursion++; |
2076 |
+ perf_nested_start(ctx, PERFT_CONTAINER, PERFT_SCAN); |
|
2076 | 2077 |
switch(type) { |
2077 | 2078 |
case CL_TYPE_IGNORED: |
2078 | 2079 |
break; |
... | ... |
@@ -2306,6 +2474,7 @@ static int magic_scandesc(int desc, cli_ctx *ctx, cli_file_t type) |
2306 | 2306 |
default: |
2307 | 2307 |
break; |
2308 | 2308 |
} |
2309 |
+ perf_nested_stop(ctx, PERFT_CONTAINER, PERFT_SCAN); |
|
2309 | 2310 |
ctx->recursion--; |
2310 | 2311 |
ctx->container_type = current_container_type; |
2311 | 2312 |
ctx->container_size = current_container_size; |
... | ... |
@@ -2347,22 +2516,26 @@ static int magic_scandesc(int desc, cli_ctx *ctx, cli_file_t type) |
2347 | 2347 |
case CL_TYPE_TEXT_UTF16BE: |
2348 | 2348 |
case CL_TYPE_TEXT_UTF16LE: |
2349 | 2349 |
case CL_TYPE_TEXT_UTF8: |
2350 |
+ perf_nested_start(ctx, PERFT_SCRIPT, PERFT_SCAN); |
|
2350 | 2351 |
if((DCONF_DOC & DOC_CONF_SCRIPT) && dettype != CL_TYPE_HTML) |
2351 | 2352 |
ret = cli_scanscript(ctx); |
2352 | 2353 |
if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX) && ret != CL_VIRUS && (ctx->container_type == CL_TYPE_MAIL || dettype == CL_TYPE_MAIL)) { |
2353 | 2354 |
lseek(desc, 0, SEEK_SET); |
2354 | 2355 |
ret = cli_scandesc(desc, ctx, CL_TYPE_MAIL, 0, NULL, AC_SCAN_VIR, NULL); |
2355 | 2356 |
} |
2357 |
+ perf_nested_stop(ctx, PERFT_SCRIPT, PERFT_SCAN); |
|
2356 | 2358 |
break; |
2357 | 2359 |
/* Due to performance reasons all executables were first scanned |
2358 | 2360 |
* in raw mode. Now we will try to unpack them |
2359 | 2361 |
*/ |
2360 | 2362 |
case CL_TYPE_MSEXE: |
2363 |
+ perf_nested_start(ctx, PERFT_PE, PERFT_SCAN); |
|
2361 | 2364 |
if(SCAN_PE && ctx->dconf->pe) { |
2362 | 2365 |
unsigned int corrupted_input = ctx->corrupted_input; |
2363 | 2366 |
ret = cli_scanpe(ctx); |
2364 | 2367 |
ctx->corrupted_input = corrupted_input; |
2365 | 2368 |
} |
2369 |
+ perf_nested_stop(ctx, PERFT_PE, PERFT_SCAN); |
|
2366 | 2370 |
break; |
2367 | 2371 |
default: |
2368 | 2372 |
break; |
... | ... |
@@ -2383,7 +2556,9 @@ static int magic_scandesc(int desc, cli_ctx *ctx, cli_file_t type) |
2383 | 2383 |
case CL_EMAXFILES: |
2384 | 2384 |
cli_dbgmsg("Descriptor[%d]: %s\n", desc, cl_strerror(ret)); |
2385 | 2385 |
case CL_CLEAN: |
2386 |
+ perf_start(ctx, PERFT_CACHE); |
|
2386 | 2387 |
cache_add(hash, hashed_size, ctx); |
2388 |
+ perf_stop(ctx, PERFT_CACHE); |
|
2387 | 2389 |
ret_from_magicscan(CL_CLEAN); |
2388 | 2390 |
default: |
2389 | 2391 |
ret_from_magicscan(ret); |
... | ... |
@@ -2427,6 +2602,7 @@ int cl_scandesc_callback(int desc, const char **virname, unsigned long int *scan |
2427 | 2427 |
free(ctx.fmap); |
2428 | 2428 |
return CL_EMEM; |
2429 | 2429 |
} |
2430 |
+ perf_init(&ctx); |
|
2430 | 2431 |
|
2431 | 2432 |
#ifdef HAVE__INTERNAL__SHA_COLLECT |
2432 | 2433 |
if(scanoptions & CL_SCAN_INTERNAL_COLLECT_SHA) { |
... | ... |
@@ -2451,6 +2627,7 @@ int cl_scandesc_callback(int desc, const char **virname, unsigned long int *scan |
2451 | 2451 |
if(rc == CL_CLEAN && ctx.found_possibly_unwanted) |
2452 | 2452 |
rc = CL_VIRUS; |
2453 | 2453 |
cli_logg_unsetup(); |
2454 |
+ perf_done(&ctx); |
|
2454 | 2455 |
return rc; |
2455 | 2456 |
} |
2456 | 2457 |
|
... | ... |
@@ -28,9 +28,6 @@ |
28 | 28 |
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
29 | 29 |
##### |
30 | 30 |
|
31 |
-# ClamAV: filter -Werror here |
|
32 |
-CFLAGS=`echo "@CFLAGS@" | sed -e 's/-Werror[^=-]//'` |
|
33 |
- |
|
34 | 31 |
ACLOCAL_AMFLAGS = -I m4 |
35 | 32 |
AUTOMAKE_OPTIONS = foreign |
36 | 33 |
AM_CPPFLAGS = |
... | ... |
@@ -140,6 +137,12 @@ CLEANFILES += libltdl.la \ |
140 | 140 |
CLEANFILES += $(ltdl_LIBOBJS) $(ltdl_LTLIBOBJS) |
141 | 141 |
|
142 | 142 |
EXTRA_DIST += COPYING.LIB \ |
143 |
+ \ |
|
144 |
+ \ |
|
145 |
+ \ |
|
146 |
+ \ |
|
147 |
+ \ |
|
148 |
+ \ |
|
143 | 149 |
README |
144 | 150 |
|
145 | 151 |
## --------------------------- ## |
... | ... |
@@ -154,7 +157,6 @@ EXTRA_DIST += argz_.h \ |
154 | 154 |
# doesn't have one that works with the given compiler. |
155 | 155 |
all-local $(lib_OBJECTS): $(ARGZ_H) |
156 | 156 |
argz.h: argz_.h |
157 |
- $(mkinstalldirs) . |
|
158 | 157 |
cp $(srcdir)/argz_.h $@-t |
159 | 158 |
mv $@-t $@ |
160 | 159 |
MOSTLYCLEANFILES += argz.h \ |
... | ... |
@@ -201,9 +201,7 @@ BUILD_CONFIGURE_FLAGS = @BUILD_CONFIGURE_FLAGS@ |
201 | 201 |
CC = @CC@ |
202 | 202 |
CCDEPMODE = @CCDEPMODE@ |
203 | 203 |
CFGDIR = @CFGDIR@ |
204 |
- |
|
205 |
-# ClamAV: filter -Werror here |
|
206 |
-CFLAGS = `echo "@CFLAGS@" | sed -e 's/-Werror[^=-]//'` |
|
204 |
+CFLAGS = @CFLAGS@ |
|
207 | 205 |
CHECK_CPPFLAGS = @CHECK_CPPFLAGS@ |
208 | 206 |
CHECK_LIBS = @CHECK_LIBS@ |
209 | 207 |
CLAMAVGROUP = @CLAMAVGROUP@ |
... | ... |
@@ -962,7 +960,6 @@ uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES \ |
962 | 962 |
# doesn't have one that works with the given compiler. |
963 | 963 |
all-local $(lib_OBJECTS): $(ARGZ_H) |
964 | 964 |
argz.h: argz_.h |
965 |
- $(mkinstalldirs) . |
|
966 | 965 |
cp $(srcdir)/argz_.h $@-t |
967 | 966 |
mv $@-t $@ |
968 | 967 |
|
... | ... |
@@ -342,6 +342,7 @@ const struct clam_option __clam_options[] = { |
342 | 342 |
#ifdef HAVE__INTERNAL__SHA_COLLECT |
343 | 343 |
{ "DevCollectHashes", "dev-collect-hashes", 0, TYPE_BOOL, MATCH_BOOL, -1, NULL, FLAG_HIDDEN, OPT_CLAMD | OPT_CLAMSCAN, "", "" }, |
344 | 344 |
#endif |
345 |
+ { "DevPerformance", "dev-performance", 0, TYPE_BOOL, MATCH_BOOL, -1, NULL, FLAG_HIDDEN, OPT_CLAMD | OPT_CLAMSCAN, "", "" }, |
|
345 | 346 |
{ "DevLiblog", "dev-liblog", 0, TYPE_BOOL, MATCH_BOOL, -1, NULL, FLAG_HIDDEN, OPT_CLAMD, "", "" }, |
346 | 347 |
|
347 | 348 |
/* Freshclam-only entries */ |
... | ... |
@@ -385,6 +385,9 @@ |
385 | 385 |
/* Define to 1 if you have the <sys/stat.h> header file. */ |
386 | 386 |
#define HAVE_SYS_STAT_H 1 |
387 | 387 |
|
388 |
+/* Define to 1 if you have the <sys/times.h> header file. */ |
|
389 |
+/* #undef HAVE_SYS_TIMES_H */ |
|
390 |
+ |
|
388 | 391 |
/* Define to 1 if you have the <sys/types.h> header file. */ |
389 | 392 |
#define HAVE_SYS_TYPES_H 1 |
390 | 393 |
|
... | ... |
@@ -502,7 +505,7 @@ |
502 | 502 |
/* #undef USE_SYSLOG */ |
503 | 503 |
|
504 | 504 |
/* Version number of package */ |
505 |
-#define VERSION "clamav-0.97" |
|
505 |
+#define VERSION "devel-clamav-0.97-17-ge0aab5d" |
|
506 | 506 |
|
507 | 507 |
/* Version suffix for package */ |
508 | 508 |
#define VERSION_SUFFIX "" |
... | ... |
@@ -467,7 +467,7 @@ int CLAMAPI Scan_CreateInstance(CClamAVScanner **ppScanner) { |
467 | 467 |
FAIL(CL_EMEM, "add_instance failed"); |
468 | 468 |
} |
469 | 469 |
unlock_engine(); |
470 |
- inst->scanopts = CL_SCAN_STDOPT; |
|
470 |
+ inst->scanopts = CL_SCAN_STDOPT | CL_SCAN_PERFORMANCE_INFO; |
|
471 | 471 |
*ppScanner = (CClamAVScanner *)inst; |
472 | 472 |
logg("Created new instance %p\n", inst); |
473 | 473 |
WIN(); |