diff --git a/commandline.c b/commandline.c index 90d1a4ca..d8b3d40c 100644 --- a/commandline.c +++ b/commandline.c @@ -2282,6 +2282,12 @@ int app_network_scan(const struct cli_parsed *parsed, struct cli_context *contex return mdp.error.error; } +int app_mem_test(const struct cli_parsed *parsed, struct cli_context *context) +{ + WHYF("Memory usage is %lldkB",memory_footprint()); + return 0; +} + int app_smac_test(const struct cli_parsed *parsed, struct cli_context *context) { if (config.debug.verbose) @@ -2293,6 +2299,8 @@ int app_smac_test(const struct cli_parsed *parsed, struct cli_context *context) const char *message; cli_arg(parsed, "message", &message, NULL, ""); + long long memory_before=memory_footprint(); + stats_handle *h=stats_new_handle(dictionary); if (!h) { WHYF("Could not load smac dictionary file '%s'",dictionary); @@ -2308,6 +2316,12 @@ int app_smac_test(const struct cli_parsed *parsed, struct cli_context *context) WHYF("Compressed message is %d bits long (%2.1f%% of original size).", c->bits_used,c->bits_used*100.0/(strlen(message)*8)); + long long memory_after=memory_footprint(); + if (memory_before>-1&&memory_after>=-1) + WHYF("Compressing increased baseline VM size by %lldkB",memory_after-memory_before); + else + WHYF("Couldn't determine memory usage."); + { int lenout=0; char mout[1025]; @@ -2327,10 +2341,19 @@ int app_smac_test(const struct cli_parsed *parsed, struct cli_context *context) return -1; } WHYF("Decompression worked fine."); + + memory_after=memory_footprint(); + if (memory_before>-1&&memory_after>=-1) + WHYF("Decompressing increased baseline VM size by %lldkB",memory_after-memory_before); range_coder_free(d); } range_coder_free(c); + memory_after=memory_footprint(); + if (memory_before>-1&&memory_after>=-1) + WHYF("After cleanup, VM size is %lldkB above baseline", + memory_after-memory_before); + return 0; } @@ -2441,6 +2464,8 @@ struct cli_schema command_line_options[]={ "Run cryptography speed test"}, {app_nonce_test,{"test","nonce",NULL}, 0, "Run nonce generation test"}, + {app_mem_test,{"test","memory","size",NULL}, 0, + "Report minimum memory usage of servald"}, {app_smac_test,{"test","smac","","",NULL}, 0, "Test SMAC short-message compression library"}, {app_slip_test,{"test","slip","[--seed=]","[--duration=|--iterations=]",NULL}, 0, diff --git a/configure.in b/configure.in index 280b828b..c0cc4639 100644 --- a/configure.in +++ b/configure.in @@ -89,6 +89,7 @@ AC_CHECK_HEADERS( linux/ioctl.h \ linux/netlink.h \ linux/rtnetlink.h \ + mach/mach.h \ net/if.h \ netinet/in.h \ ifaddrs.h \ diff --git a/os.c b/os.c index c1b4fdfc..b33df58a 100644 --- a/os.c +++ b/os.c @@ -30,6 +30,49 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include #include +#ifdef HAVE_MACH_MACH_H +#include +#endif + +#ifdef HAVE_MACH_MACH_H + +long long memory_footprint() +{ + struct task_basic_info t_info; + mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; + + if (KERN_SUCCESS != task_info(mach_task_self(), + TASK_BASIC_INFO, (task_info_t)&t_info, + &t_info_count)) + { + return -1; + } + return t_info.resident_size/1024LL; +} +#else +long long memory_footprint() +{ + FILE *f=fopen("/proc/self/status","r"); + if (f) { + long long kb; + char line[1024]; + line[0]=0; fgets(line,1024,f); + while(line[0]) { + if (sscanf(line,"VmSize: %lld",&kb)==1) { + fclose(f); + return kb; + } + line[0]=0; fgets(line,1024,f); + } + fclose(f); + return -1; + } else { + // no proc file, so just give up + return -1; + } + +} +#endif int mkdirs(const char *path, mode_t mode) { diff --git a/os.h b/os.h index d63f7b1e..ec2c3ef7 100644 --- a/os.h +++ b/os.h @@ -121,4 +121,9 @@ int urandombytes(unsigned char *buf, unsigned long long len); */ ssize_t read_symlink(const char *path, char *buf, size_t len); +/* Return the current process size (all inclusive VM size, not resident size + or data page size) in KB. + @author Paul Gardner-Stephen */ +long long memory_footprint(); + #endif //__SERVALDNA_OS_H