Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions src/stackusage
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ showusage()
echo "designed to work in resource-constrained environments, such as "
echo "embedded systems."
echo ""
echo "Usage: stackusage [-d] [-o PATH] [-s SIG] PROG [ARGS..]"
echo "Usage: stackusage [-d] [-h] [-o PATH] [-s SIG] PROG [ARGS..]"
echo " or: stackusage --help"
echo " or: stackusage --version"
echo ""
echo "Options:"
echo " -d debug mode, running program through debugger"
echo " -h human-readable output (show sizes in KB/MB instead of bytes)"
echo " -o <PATH> write output to specified file path, instead of stderr"
echo " -s <SIG> enable on-demand logging when signalled SIG signal"
echo " PROG program to run and analyze"
Expand Down Expand Up @@ -85,7 +86,8 @@ fi
DEBUG="0"
SIGNO=""
OUTFILE=""
while getopts "?do:s:" OPT; do
HUMAN="0"
while getopts "?dho:s:" OPT; do
case "${OPT}" in
\?)
showusage
Expand All @@ -94,6 +96,9 @@ while getopts "?do:s:" OPT; do
d)
DEBUG="1"
;;
h)
HUMAN="1"
;;
o)
OUTFILE="${OPTARG}"
;;
Expand Down Expand Up @@ -180,13 +185,15 @@ while [ "${LIBPATHS[CNT]}" != "" ]; do
if [ "${DEBUG}" == "0" ]; then
SU_FILE="${TMPLOG}${OUTFILE}" \
SU_SIGNO="${SIGNO}" \
SU_HUMAN="${HUMAN}" \
LD_PRELOAD="${LIBPATH}" \
DYLD_INSERT_LIBRARIES="${LIBPATH}" \
"${@:1}"
else
LLDBCMDPATH="${TMP}/lldb.cmd"
echo "env SU_FILE=\"${TMPLOG}${OUTFILE}\"" > "${LLDBCMDPATH}"
echo "env SU_SIGNO=\"${SIGNO}\"" >> "${LLDBCMDPATH}"
echo "env SU_HUMAN=\"${HUMAN}\"" >> "${LLDBCMDPATH}"
echo "env LD_PRELOAD=\"${LIBPATH}\"" >> "${LLDBCMDPATH}"
echo "env DYLD_INSERT_LIBRARIES=\"${LIBPATH}\"" >> "${LLDBCMDPATH}"
echo "run ${@:2}" >> "${LLDBCMDPATH}"
Expand Down
75 changes: 61 additions & 14 deletions src/sumain.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#define SU_ENV_STDERR "SU_STDERR"
#define SU_ENV_SIGNO "SU_SIGNO"
#define SU_ENV_SYSLOG "SU_SYSLOG"
#define SU_ENV_HUMAN "SU_HUMAN"
#define SU_FILL_BYTE 0xcd
#define SU_FILL_OFFSET 512
#define SU_GROW_MARGIN (256*1024)
Expand Down Expand Up @@ -128,6 +129,7 @@ static int su_inited = 0;
static int su_log_signo = 0;
static int su_log_stderr = 0;
static int su_log_syslog = 0;
static int su_log_human = 0;
static char *su_log_file = NULL;
static struct su_threadinfo_s *threadinfo_head = NULL;
static pthread_mutex_t threadinfo_mx = PTHREAD_MUTEX_INITIALIZER;
Expand Down Expand Up @@ -526,6 +528,19 @@ static void su_thread_init(su_threadtype_t threadtype, pthread_attr_t *rattr,
}


static void su_format_size_human(size_t bytes, char *buffer, size_t buflen)
{
if (bytes < 1024) {
snprintf(buffer, buflen, "%zu B", bytes);
} else if (bytes < 1024 * 1024) {
snprintf(buffer, buflen, "%.1f KB", bytes / 1024.0);
} else if (bytes < 1024 * 1024 * 1024) {
snprintf(buffer, buflen, "%.1f MB", bytes / (1024.0 * 1024.0));
} else {
snprintf(buffer, buflen, "%.1f GB", bytes / (1024.0 * 1024.0 * 1024.0));
}
}

static void su_log_stack_usage(void)
{
struct su_threadinfo_s *threadinfo_it = NULL;
Expand All @@ -539,8 +554,15 @@ static void su_log_stack_usage(void)
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
SU_LOG("%s log at %s ----------------------------------------\n",
su_name, timestamp);
SU_LOG(" pid id tid requested actual maxuse max%% dur"
" funcP name\n");

if (su_log_human) {
SU_LOG(" pid id tid requested actual maxuse max%% dur"
" funcP name\n");
} else {
SU_LOG(" pid id tid requested actual maxuse max%% dur"
" funcP name\n");
}

while(threadinfo_it)
{
int usage_percent = 0;
Expand All @@ -551,18 +573,38 @@ static void su_log_stack_usage(void)
(int) threadinfo_it->stack_req_size;
}

SU_LOG("%5d %3d %5d %9d %9d %9d %3d %5d %18p %s\n",
getpid(),
threadinfo_it->id,
threadinfo_it->tid,
(int) threadinfo_it->stack_req_size,
(int) threadinfo_it->stack_size,
(int) threadinfo_it->stack_max_usage,
(int) usage_percent,
threadinfo_it->time_duration,
threadinfo_it->func_ptr,
threadinfo_it->thread_name
);
if (su_log_human) {
char req_buf[16], actual_buf[16], max_buf[16];
su_format_size_human(threadinfo_it->stack_req_size, req_buf, sizeof(req_buf));
su_format_size_human(threadinfo_it->stack_size, actual_buf, sizeof(actual_buf));
su_format_size_human(threadinfo_it->stack_max_usage, max_buf, sizeof(max_buf));

SU_LOG("%5d %3d %5d %10s %10s %10s %3d %5d %18p %s\n",
getpid(),
threadinfo_it->id,
threadinfo_it->tid,
req_buf,
actual_buf,
max_buf,
(int) usage_percent,
threadinfo_it->time_duration,
threadinfo_it->func_ptr,
threadinfo_it->thread_name
);
} else {
SU_LOG("%5d %3d %5d %9d %9d %9d %3d %5d %18p %s\n",
getpid(),
threadinfo_it->id,
threadinfo_it->tid,
(int) threadinfo_it->stack_req_size,
(int) threadinfo_it->stack_size,
(int) threadinfo_it->stack_max_usage,
(int) usage_percent,
threadinfo_it->time_duration,
threadinfo_it->func_ptr,
threadinfo_it->thread_name
);
}

threadinfo_it = threadinfo_it->next;
}
Expand Down Expand Up @@ -678,6 +720,11 @@ static void su_get_env(void)
su_log_signo = strtol(getenv(SU_ENV_SIGNO), NULL, 10);
}

if(getenv(SU_ENV_HUMAN))
{
su_log_human = strtol(getenv(SU_ENV_HUMAN), NULL, 10);
}

su_log_file = getenv(SU_ENV_FILE);
}

Loading