diff --git a/TraceScreen.c b/TraceScreen.c index 072c26d..087e6cc 100644 --- a/TraceScreen.c +++ b/TraceScreen.c @@ -23,11 +23,17 @@ in the source distribution for its full text. /*{ +typedef enum TraceType_ { + STRACE, + LTRACE +} TraceType; + typedef struct TraceScreen_ { Process* process; Panel* display; FunctionBar* bar; bool tracing; + TraceType type; } TraceScreen; }*/ @@ -38,9 +44,10 @@ static char* tbKeys[3] = {"F4", "F5", "Esc"}; static int tbEvents[3] = {KEY_F(4), KEY_F(5), 27}; -TraceScreen* TraceScreen_new(Process* process) { +TraceScreen* TraceScreen_new(Process* process, TraceType type) { TraceScreen* this = (TraceScreen*) malloc(sizeof(TraceScreen)); this->process = process; + this->type = type; this->display = Panel_new(0, 1, COLS, LINES-2, LISTITEM_CLASS, true, ListItem_compare); this->bar = FunctionBar_new(3, tbFunctions, tbKeys, tbEvents); this->tracing = true; @@ -56,7 +63,14 @@ void TraceScreen_delete(TraceScreen* this) { static void TraceScreen_draw(TraceScreen* this) { attrset(CRT_colors[PANEL_HEADER_FOCUS]); mvhline(0, 0, ' ', COLS); - mvprintw(0, 0, "Trace of process %d - %s", this->process->pid, this->process->comm); + switch(this->type) { + case STRACE: + mvprintw(0, 0, "Trace of process %d - %s (STRACE)", this->process->pid, this->process->comm); + break; + case LTRACE: + mvprintw(0, 0, "Trace of process %d - %s (LTRACE)", this->process->pid, this->process->comm); + break; + } attrset(CRT_colors[DEFAULT_COLOR]); FunctionBar_draw(this->bar, NULL); } @@ -73,15 +87,24 @@ void TraceScreen_run(TraceScreen* this) { dup2(fdpair[1], STDERR_FILENO); fcntl(fdpair[1], F_SETFL, O_NONBLOCK); sprintf(buffer, "%d", this->process->pid); - execlp("strace", "strace", "-p", buffer, NULL); - const char* message = "Could not execute 'strace'. Please make sure it is available in your $PATH."; + const char* message; + switch(this->type) { + case STRACE: + execlp("strace", "strace", "-p", buffer, NULL); + message = "Could not execute 'strace'. Please make sure it is available in your $PATH."; + break; + case LTRACE: + execlp("ltrace", "ltrace", "-p", buffer, NULL); + message = "Could not execute 'ltrace'. Please make sure it is available in your $PATH."; + break; + } write(fdpair[1], message, strlen(message)); exit(1); } fcntl(fdpair[0], F_SETFL, O_NONBLOCK); - FILE* strace = fdopen(fdpair[0], "r"); + FILE* trace = fdopen(fdpair[0], "r"); Panel* panel = this->display; - int fd_strace = fileno(strace); + int fd_trace = fileno(trace); TraceScreen_draw(this); CRT_disableDelay(); bool contLine = false; @@ -90,13 +113,13 @@ void TraceScreen_run(TraceScreen* this) { while (looping) { fd_set fds; FD_ZERO(&fds); - FD_SET(fd_strace, &fds); + FD_SET(fd_trace, &fds); struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 500; - int ready = select(fd_strace+1, &fds, NULL, NULL, &tv); + int ready = select(fd_trace+1, &fds, NULL, NULL, &tv); int nread = 0; if (ready > 0) - nread = fread(buffer, 1, 1000, strace); + nread = fread(buffer, 1, 1000, trace); if (nread && this->tracing) { char* line = buffer; buffer[nread] = '\0'; @@ -164,6 +187,6 @@ void TraceScreen_run(TraceScreen* this) { } kill(child, SIGTERM); waitpid(child, NULL, 0); - fclose(strace); + fclose(trace); CRT_enableDelay(); } diff --git a/TraceScreen.h b/TraceScreen.h index d2904a7..cad4450 100644 --- a/TraceScreen.h +++ b/TraceScreen.h @@ -25,15 +25,21 @@ in the source distribution for its full text. #include "FunctionBar.h" +typedef enum TraceType_ { + STRACE, + LTRACE +} TraceType; + typedef struct TraceScreen_ { Process* process; Panel* display; FunctionBar* bar; bool tracing; + TraceType type; } TraceScreen; -TraceScreen* TraceScreen_new(Process* process); +TraceScreen* TraceScreen_new(Process* process, TraceType type); void TraceScreen_delete(TraceScreen* this); diff --git a/htop.1 b/htop.1 index 57c7012..27ae732 100644 --- a/htop.1 +++ b/htop.1 @@ -35,6 +35,11 @@ Trace process system calls: if strace(1) is installed, pressing this key will attach it to the currently selected process, presenting a live update of system calls issued by the process. .TP +.B l +Trace process library calls: if ltrace(1) is installed, pressing this key +will attach it to the currently selected process, presenting a live +update of library calls issued by the process. +.TP .B F1, h Help screen .TP diff --git a/htop.c b/htop.c index c74b6b3..42d1aca 100644 --- a/htop.c +++ b/htop.c @@ -117,6 +117,7 @@ static void showHelp(ProcessList* pl) { mvaddstr(19, 0, " F2 S: setup F6 >: select sort column"); mvaddstr(20, 0, " F1 h: show this help screen"); mvaddstr(21, 0, " F10 q: quit s: trace syscalls with strace"); + mvaddstr(22, 0, " l: trace library calls with ltrace"); attrset(CRT_colors[HELP_BOLD]); mvaddstr( 9, 0, " Arrows"); mvaddstr( 9,40, " F5 t"); @@ -134,10 +135,11 @@ static void showHelp(ProcessList* pl) { mvaddstr(19, 0, " F2 S"); mvaddstr(19,40, " F6 >"); mvaddstr(20, 0, " F1 h"); mvaddstr(21, 0, " F10 q"); mvaddstr(21,40, " s"); + mvaddstr(22,40, " l"); attrset(CRT_colors[DEFAULT_COLOR]); attrset(CRT_colors[HELP_BOLD]); - mvaddstr(23,0, "Press any key to return."); + mvaddstr(24,0, "Press any key to return."); attrset(CRT_colors[DEFAULT_COLOR]); refresh(); CRT_readKey(); @@ -542,9 +544,20 @@ int main(int argc, char** argv) { Panel_onKey(panel, KEY_DOWN); break; } + case 'l': + { + TraceScreen* ts = TraceScreen_new((Process*) Panel_getSelected(panel), LTRACE); + TraceScreen_run(ts); + TraceScreen_delete(ts); + clear(); + FunctionBar_draw(defaultBar, NULL); + refreshTimeout = 0; + CRT_enableDelay(); + break; + } case 's': { - TraceScreen* ts = TraceScreen_new((Process*) Panel_getSelected(panel)); + TraceScreen* ts = TraceScreen_new((Process*) Panel_getSelected(panel), STRACE); TraceScreen_run(ts); TraceScreen_delete(ts); clear();