| Add support for 'ltrace' in addition to 'strace' support. |
| Index: htop/TraceScreen.c |
| =================================================================== |
| --- htop.orig/TraceScreen.c 2011-01-16 17:02:59.000000000 +0200 |
| +++ htop/TraceScreen.c 2011-01-16 18:15:07.000000000 +0200 |
| @@ -23,11 +23,17 @@ |
| |
| /*{ |
| |
| +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 int tsEvents[] = {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(tsFunctions, tsKeys, tsEvents); |
| this->tracing = true; |
| @@ -56,7 +63,14 @@ |
| 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 @@ |
| 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 @@ |
| 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'; |
| @@ -171,6 +194,6 @@ |
| } |
| kill(child, SIGTERM); |
| waitpid(child, NULL, 0); |
| - fclose(strace); |
| + fclose(trace); |
| CRT_enableDelay(); |
| } |
| Index: htop/TraceScreen.h |
| =================================================================== |
| --- htop.orig/TraceScreen.h 2009-06-29 13:18:40.000000000 +0300 |
| +++ htop/TraceScreen.h 2011-01-16 18:15:07.000000000 +0200 |
| @@ -25,15 +25,21 @@ |
| #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); |
| |
| Index: htop/htop.1 |
| =================================================================== |
| --- htop.orig/htop.1 2011-01-16 17:02:59.000000000 +0200 |
| +++ htop/htop.1 2011-01-16 18:15:07.000000000 +0200 |
| @@ -54,6 +54,11 @@ |
| Display open files for a process: if lsof(1) is installed, pressing this key |
| will display the list of file descriptors opened 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 |
| Index: htop/htop.c |
| =================================================================== |
| --- htop.orig/htop.c 2011-01-16 17:02:59.000000000 +0200 |
| +++ htop/htop.c 2011-01-16 18:15:07.000000000 +0200 |
| @@ -133,6 +133,7 @@ |
| mvaddstr(19, 0, " F2 S: setup F6 >: select sort column"); |
| mvaddstr(20, 0, " F1 h: show this help screen l: list open files with lsof"); |
| 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"); |
| @@ -152,10 +153,11 @@ |
| mvaddstr(19, 0, " F2 S"); mvaddstr(19,40, " F6 >"); |
| mvaddstr(20, 0, " ? F1 h"); mvaddstr(20,40, " l"); |
| 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(); |
| @@ -580,9 +582,20 @@ |
| 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(); |