If a fatal error occurs before CRT_init has been called, CRT_done
dereferences NULL in CRT_colors.
Simply check if CRT_crashSettings is not NULL, which is eventually
set when CRT_init has been called.
If it is not set, then do not try to disable ncurses.
Proof of Concept (on Linux):
$ ./configure --with-proc=/var/empty
$ make
$ ./htop
As the loop checks `tree_depth`, a tree build is needed to ensure
they're filled in correctly. Note that this breaks the display list sort
order in case it's non-tree-based (either startup in flat mode, or `*`
hotkey in flat mode), so the display list will need to be sorted again.
The PROCESS_MAX_UID_DIGITS=19 introduced in
696f79fe5099d510fc6ecc6d1e2f0ab3ae29e04e doesn't make sense.
The `uid_t` type does not require to be signed in POSIX. If we are to
support 64 bits as the maximum size of `uid_t`, then
PROCESS_MAX_UID_DIGITS should be 20. (= floor(log10(UINT64_MAX)) + 1).
Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
* The size of titleBuffer should be 257 bytes, not 256.
* Remove redundant `static char titleBuffer[]` delarations within
`alignedProcessFieldTitle()` and let the subroutine use one shared
buffer for printing field title. This reduces code size.
Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
Title width of "CPUD%" and "SWAPD%" is 5 and there value cannot go
beyond "100.0%", so increase their field width to 5.
"IOD%" is similar to "MEM%" column, title width is 4 and maximum value
cannot go beyond "100.0%". So in case of "IOD%" column, there is no need
to increase title width to "5". "Process_printPercentage()" function
will handle the maximum value case, it will display value beyond "99.9%"
as "100" instead of "100.0".
Since commit edf319e[1], we're dynamically adjusting column width of
"CPU%", showing single digit precision also for values greater than
"99.9%" makes "CPU%" column consistent with all other values.
[1]: edf319e53d1fb77546505e238d75160a3febe56e
Change "Process_printPercentage()" function's logic to always display
value (i.e. "val") with single precision. Except when value is greater
than "99.9%" for columns like "MEM%", whose width is fixed to "4" and
value cannot go beyond "100%".
Credits: @Explorer09, thanks for the patch[2] to fix title alignment
issue.
[2]: https://github.com/htop-dev/htop/pull/959#issuecomment-1092480951Closes: #957
This fixes an issus in Hashtable_dump where `"(nil"` is passed as an
argument to `%p` in fprintf. This prints the static address of `"(nil)"`
not "(nil)". This commit changes the code to just pass the NULL pointer
to fprintf, which will consistently print "0x0".
As the "highlight dying processes" option has to keep processes in the
list when they disappear, no code except the cleanup loop in
`ProcessList_scan` should remove processes from the list directly.
Remove the export to prevent random process removals from being
reintroduced accidentally.
If a process goes away while reading its fields, but we already have
that process in the list, we should keep it in case the "highlight dying
processes" mode is active. Not only is that expected in this mode, but
this should also ensure parents are in the list when their children are
(wanted for tree mode consistency).
A process can die between reading the directory listing and opening the
directory FD (if HAVE_OPENAT) or /proc files (otherwise) for reading the
process data. This race would cause LinuxProcessList_recurseProcTree to
remove it from the list immediately, which is unexpected in the
"highlight dying processes" mode and can break the tree structure.
This patch closes this race in the HAVE_OPENAT case by only accessing
the process entry after the directory FD has been opened.
man sscanf(3):
A sequence of white-space characters (space, tab, newline, etc.; see isspace(3)).
This directive matches any amount of white space, including none, in the input.
This commit changes ProcessList_scan to lazily remove Processes by
index, which is known, instead of performing a brute-force search by
pid and immediately reclaiming the lost vector space via compaction.
Searching by pid is potentially quadratic in ProcessList_scan because
the process we are searching for is always at the back of the vector
(the scan starts from the back of the vector). Additionally, removal
via Vector_remove immediately reclaims space (by sliding elements
down).
With these changes process removal in ProcessList_scan is now linear.
Changes:
* ProcessList: add new ProcessList_removeIndex function to remove
by index
* Vector: add Vector_softRemove and Vector_compact functions to
support lazy removal/deletion of entries Vector_softRemove
Vector_compact
* Vector: replace Vector_count with Vector_countEquals since it only
used for consistency assertions.
Coverity scan reports that there is dead code in Settings_write
checking for nulls that have already been dereferenced on every
code path leading to the check. This is likely a hangover from
times when the screens pointer was only conditionally allocated
- they're not needed anymore.
Coverity scan reports there may be a code path that would cause
an overrun in the (relatively new) ScreenSettings code where it
evaluates default sort direction. Add bounds check and default
to descending instead of a potentially invalid array access.
If the max PID or UID value for a platform is exactly a power of ten
(10000, 100000, etc.) the column widths of PID and UID would be 1 char
less than the correct number of digits. This is caused by the wrong
rounding function (ceil(x)); change to the correct one (trunc(x) + 1).
Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
Get this warning when compiling Settings.c on the Mac OS X with clang-800.0.42.1.
Settings.c:447:28: warning: comparison of unsigned enum expression < 0 is always false [-Wtautological-compare]
if (this->hLayout < 0 || this->hLayout >= LAST_HEADER_LAYOUT)
~~~~~~~~~~~~~ ^ ~
This patch fixes the problem.
Retrieve hwloc dependencies through pkg-config to avoid the following
static build failure:
checking for hwloc_get_proc_cpubind in -lhwloc... no
configure: error: can not find required library libhwloc
This build failure is raised because without pkg-config, hwloc
dependencies such as libxml2 are not retrieved:
configure:8999: checking for hwloc_get_proc_cpubind in -lhwloc
configure:9022: /home/autobuild/autobuild/instance-0/output-1/host/bin/powerpc-buildroot-linux-uclibc-gcc -o conftest -D_GNU_SOURCE -I/home/autobuild/autobuild/instance-0/output-1/host/powerpc-buildroot-linux-uclibc/sysroot/usr/bin/../../usr/include -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Og -g0 -static -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -static conftest.c -lhwloc -llzma -L/home/autobuild/autobuild/instance-0/output-1/host/powerpc-buildroot-linux-uclibc/sysroot/usr/bin/../../usr/lib -lncurses -lm >&5
/home/autobuild/autobuild/instance-0/output-1/host/lib/gcc/powerpc-buildroot-linux-uclibc/10.3.0/../../../../powerpc-buildroot-linux-uclibc/bin/ld: /home/autobuild/autobuild/instance-0/output-1/host/powerpc-buildroot-linux-uclibc/sysroot/usr/bin/../../usr/lib/libhwloc.a(topology-xml-libxml.o): in function `hwloc_libxml_free_buffer':
topology-xml-libxml.c:(.text+0x6a): undefined reference to `xmlFree'
Fixes:
- http://autobuild.buildroot.org/results/5d815ec08c580005a863df6ac9ac29deff7d4128
Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
At the moment this is used to make the memory meter report sane values even
if the host has ZFS and that leaks through into a containerized environment
Fixes#863
Includes a clever check for magic PROC_PID_INIT_INO in /proc/self/ns/pid thanks to Pavel Snajdr (snajpa)
This enables:
* Multiple filters in the main panel and strace etc. views
* Multiple search terms
The search terms are separated by "|" and are still fixed strings
matched case-insensitive.
Added a multi flag at request of BenBE.
SELinux contexts can be quite long; adjust the column width dynamically
at each cycle to the longest value.
Also with the recent addition of multiple screens, over-long columns can
be moved into their own screen.
Depending upon default behavior of the compiler and floating-point
environment, compiler could round down the value between "99.9" and
"100.0" to "99.0", instead of rounding it to the nearest value, "100.0".
Note: The floating-point environment access and modification is only
meaningful when "#pragma STD FENV_ACCESS" is set to "ON"[1]. Otherwise
implementation is free to assume that floating-point control modes are
always the default. So it would be a good idea to address the rounding
ambiguity between "99.9" and "100.0" to become compiler agnostic.
[1]: https://en.cppreference.com/w/c/numeric/fenv
Credits: @Explorer09, thanks for the suggestion.
When we run a process which utilizes CPU between 100.0% and 999.9%, htop
shows an unnecessary decimal character at the end of the value. For
example, '100.x' and '247.x' become '100.' and '247.' respectively.
When CPU utilization is less than and equal to '99.9%', show the result
with single digit precision and if result is less than four characters,
pad it with the blank space. When CPU utilization is greater than
'99.9%', show only integral part of the result and if it's less than
four characters, pad it with the blank space.
Closes: #946
Fetching the TTY name of a process is extremely expensive on darwin and
the call to devname accounts for 95% of htop's CPU usage when there is
high process turnover (this is mostly due to devname calling lstat,
which is incredibly slow). This can make htop unresponsive.
To mitigate this only set the process TTY name if the it is being
actively displayed (PROCESS_FLAG_TTY), which by default it is not
on darwin.
ProcessList_buildTree does not need any particular sort order for
children of the same process or roots. Switching these to the sort order
configured by the user produces sorted tree automatically, making repeat
sort unnecessary.
ProcessList_buildTreeBranch used to search for children with a linear
scan of the process table, which made tree build time quadratic in
process count. Pre-sorting the list by parent PID (if known) makes it
possible to select the correct slice by bisection much faster.
Separate `processes` (the vector owning the processes, sorted in
whatever order is needed right now internally) and `displayList` (a
vector referencing the processes in the same order they're to be
displayed).
Special-casing hidden processes does not serve any obvious purpose and
depends on the move from processes to processes2 which will be removed
in a later commit.
htop is a program which will be run on CHOST after cross-compilation;
CTARGET is only for a small number of cases where a program itself outputs
code (so you might cross-compile a compiler which spits out code for a third
architecture/platform).
We want to use AC_CANONICAL_HOST to check CHOST for the platform currently
being used to build htop.
The confusion around this issue was compounded by a mistake in autoconf-archive
which has since been fixed (AX_PTHREAD pulled it in incorrectly).
See: https://github.com/libstatgrab/libstatgrab/pull/131
See: https://github.com/fenrus75/powertop/pull/90#discussion_r705803725
Signed-off-by: Sam James <sam@gentoo.org>
This displays the same output as ps's -o emul, which is the system call
emulation environment, or ABI, in use. This will typically be FreeBSD
ELF32 or ELF64, but can also be Linux ELF32 or Linux ELF64 when running
Linux binaries under FreeBSD's Linuxulator binary compatibility layer.
The column width of 16 is chosen to match KI_EMULNAMELEN's value of 16,
most of which is normally used up as FreeBSD ELF32/64 is 13 characters.
On the help screen's depiction of the swap bar, the / separator between
used and cache should be coloured for consistency with the other bars.
I tried removing the coloured /s from the other bars to make them
consistent, but found that less visually appealing.
The system curses library can handle terminal size changes with
SIGWINCH without asking system calls to restart, which effectively
stops system calls with -1 and EINTR. An example is ncurses on
Linux systems.
One of these system calls is waitpid. While waiting for the lsof child
to complete, a badly timed SIGWINCH can interrupt the waitpid call,
effectively never clearing the state of the child, keeping the zombie
until htop exits.
Proof of Concept:
#include <unistd.h>
int main(void) {
close(1); close(2);
sleep(5);
return 0;
}
Compile this as a replacement "lsof" and put it into your path. Make
sure that it's called instead of the real lsof.
Press "l" to list open files and resize your terminal within the next
5 seconds. You will see that a zombie process is kept by htop when the
timeout finishes.
The parent process of htop might have set SIGCHLD to ignore, which can
be inherited by htop (Linux does this, OpenBSD resets to default).
If SIGCHLD is ignored then waitpid returns -1 which is not properly
handled by htop for lsof output.
Proof of Concept (Linux):
#include <signal.h>
#include <unistd.h>
int main(void) {
char *arg[] = { "htop", NULL };
signal(SIGCHLD, SIG_IGN);
execv("htop", arg);
return 1;
}
If you run htop with ignored SIGCHLD then pressing "l" always fails,
i.e. it is not possible to list open files even if lsof is installed.
It is possible to exceed the unsigned int data type on 64 bit systems
with enough available RAM. Use size_t in all places instead.
Proof of Concept: Create a 4 GB line in .htoprc file and run htop
$ dd if=/dev/zero bs=1024 count=4194304 | tr '\0' 'a' > ~/.htoprc
$ htop
Segmentation fault
Also avoid overflow of stack based "match" array in String_getToken.
Formatting the merged command string is now implemented in an platform
independent way. Drop the Process member getCommandStr designed for
overrides of individual platforms.
When reading a configuration file with the syntax previous to the
screens update Settings_defaultScreens() will add the default fields and
later ScreenSettings_readFields() will add the ones from the
configuration file. This will duplicate some fields and corrupt the
columns due to the boundless Command field.
The libunwind headers of LLVM are located in the subdirectory
/usr/include/libunwind. Search that subdirectory when the default
header test fails. Also extend the include path due to the transitive
include of `<__libunwind_config.h>`.
Closes: #894
With a size of 2 or 3 the grow factor does not reach 70% for one empty
entry. This will cause the following assert violation:
htop: Hashtable.c:236: void Hashtable_put(Hashtable *, ht_key_t, void *): Assertion `this->size > this->items' failed.
Due to the use of prime numbers Hashtable_remove used to never shrink
from some sizes. For example, a size 8191 hashtable would try to shrink
to 4095, which nextPrime would round back to 8191 instead of the
intended 4093. A factor of 3 is enough to allow every prime size used to
shrink to the previous one.
Not all batteries entries in /sys/class/power_supply start with either
BAT or AC, but might have device specific names, e.g. CMB1.
Detect the types of those entries and parse them accordingly.
Closes: #881
Fixes: 3e70de64 ("Code clean up for reading battery info")
Show a non highlighted string at the start of htop, not the failure
text.
Also the original fix only handled the text mode, not the bar mode.
Improves: 2977414d ("Discard stale information from DiskIO and NetworkIO meters")
Related: #860
Use C99 struct initialization, which also makes using calloc redundant.
htop: Process.c:1179: int Process_compareByKey_Base(const Process *, const Process *, ProcessField): Assertion `0 && "Process_compareByKey_Base: default key reached"' failed.
If the new htop is configured with htoprc having no tabs (eg on upgrade)
then the interface will not automatically introduce/enable them.
However, for a fresh install of htop, enabling them automatically
Signed-off-by: Sohaib Mohamed <sohaib.amhmd@gmail.com>
Commit d8dfbbd3 ("Tidy up process state handling") did change the
highlighting of the UNINTERRUPTIBLE_WAIT state (D) from red to gray.
As this state might means the process probably still has work to do and
can hint at bottlenecks, revert this particular change.
Fixes: d8dfbbd3 ("Tidy up process state handling")
Do not underflow count at the last iteration, which triggers UBSAN when
using -fsanitize=unsigned-integer-overflow. This is useful as those
underflows can be a result of a flawed counting logic (e.g. a counter
gets reduced more than increased).
When we close the application using the quit function F10, the last line
is cleared so that on terminals which do not support ALTBUF the last
line is not clobbered. This do not happen when the application exits as
a result of a signal (SIGINT,SIGTERM,SIGQUIT).
Move the logic to clear the last line into the CRT_done function. This
ensures that it will be executed when the CRT_handleSIGTERM is called.
Use PF_KTHREAD flag in /proc/[pid]/stat to detect kernel threads.
This fixed an issue when a process's cmdline is empty, htop think
it is a kernel thread.
This ensures the initial read of the data is not misinterpreted as arbitrarily large values.
Also this forces the maximum update interval between two subsequent reads to within 30s.
Fixes#860
While most Unix-like systems use 16-bit user IDs,
Linux supports 32-bit UIDs since version 2.6.
UIDs above 65535 are used for UID namespacing of containers,
where a container has its own set of 16-bit user IDs.
Processes in such containers will have (much) larger UIDs than 65535.
Because the current format strings for `ST_UID` and `USER`
are `%5d` and `%9d` respectively, processes with such UIDs
lead to misaligned columns.
Dynamically scale the `ST_UID` column and increase the size of `USER`
to 10 characters (length of UINT32_MAX) to ensure that the user ID always fits.
Additionally: clean up how the titlebuffer size calculation and ensure
the PID column has a minimum size of 5.
Limit the maximum width (instead of only the minimum width), pad the
header width accordingly, and also remove extra stray spaces from the
format string (the main spacing should just come from the alignment of
the value).
Fixes#850.
The names array is terminated by a NULL entry, thus allocate space for
one more than entries.
Fixes: #844
==6708==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6060000045b8 at pc 0x000000589ee1 bp 0x7ffcd1dee220 sp 0x7ffcd1dee218
READ of size 8 at 0x6060000045b8 thread T0
#0 0x589ee0 in String_freeArray ./XUtils.c:157:23
#1 0x56c9af in Settings_delete ./Settings.c:31:7
#2 0x4ee44b in CommandLine_run ./CommandLine.c:395:4
#3 0x4d6fb2 in main ./htop.c:15:11
#4 0x7ff3b8154e49 in __libc_start_main csu/../csu/libc-start.c:314:16
#5 0x428aa9 in _start (./htop+0x428aa9)
0x6060000045b8 is located 0 bytes to the right of 56-byte region [0x606000004580,0x6060000045b8)
allocated by thread T0 here:
#0 0x4a53f2 in __interceptor_calloc (./htop+0x4a53f2)
#1 0x5890ba in xCalloc ./XUtils.c:55:17
#2 0x50a044 in Header_writeBackToSettings ./Header.c:148:34
#3 0x4de861 in Action_runSetup ./Action.c:91:7
#4 0x4de861 in actionSetup ./Action.c:386:4
#5 0x515caf in MainPanel_eventHandler ./MainPanel.c:106:19
#6 0x56a5c1 in ScreenManager_run ./ScreenManager.c:235:19
#7 0x4ee13b in CommandLine_run ./CommandLine.c:364:4
#8 0x4d6fb2 in main ./htop.c:15:11
#9 0x7ff3b8154e49 in __libc_start_main csu/../csu/libc-start.c:314:16
This is real, physical memory available for applications to
use. We should not try to pretend otherwise; its confusing
for users and inconsistent with all other tools.
This situation can arise if pcp-htop screen is resized right
at the same time sampling from pmcd(1) is happening. Have a
couple more goes at it before giving up entirely; once there
is no data available though we cannot proceed into accessing
the sample result data structure (segv will result) so a new
short-circuit guard is added there also.
This closes a nasty memory leak. There is at least another leak looming somewhere when Disk I/O is shown in the header area. That could very well be an issue within libdevstat native to FreeBSD.
Add an explicit else clause so a following else branch for a prior if
condition does not get mixed up.
Also force a trailing semicolon and thereby silence current
-Wextra-semi-stmt warnings.
Improve readability of the hwloc_bitmap_foreach_begin loop macro.
Insert space padding between a header (e.g. 'if', 'for', 'while'...) and the
following paren. ex:
if(isFoo((a+2), b))
bar(a, b);
becomes:
if (isFoo((a+2), b))
bar(a, b);
Link: http://astyle.sourceforge.net/astyle.html#_pad-paren
Signed-off-by: Sohaib Mohamed <sohaib.amhmd@gmail.com>
Fixes builds failing with error
MainPanel.c:65:62: error: 'Settings {aka struct Settings_}' has no member named 'enableMouse'
if (ch != ERR && (ch != KEY_MOUSE || this->state->settings->enableMouse))
A process, whose executable has been replaced and thus marked by htop,
can be re-executed with the replaced executable, with the same PID, in
two ways: the Linux feature checkpoint/restore or re-execution of PID 1.
The actual check is just a string comparison, like the dropped
condition, leading to (almost) no computation overhead.
htop has been licensed as GPLv2 but there was inconsistency regarding the
option to choose "any later version" as granted by the license.
This commit clarifies the htop dev team is fine with that choice.
Extending to right neighbors is intended for text meters with an
overlong content, so the whole text is shown if possible.
Multi column meters, like the combined memory and swap meter, position
its text depending on the given total width; keep the position to the
original assigned header slot.
Short term resolution for #796
Select the current active header layout, not the current saved layout
from the settings, as the value gets only saved back from the active
header to settings on closing the setup menu.
Closes: #785
Zero all the CPU data, like totalPeriod, after its memory allocation via
realloc(3).
Conditional jump or move depends on uninitialised value(s)
at 0x132A9B: LinuxProcessList_scanCPUTime (LinuxProcessList.c:1928)
by 0x1358C3: ProcessList_goThroughEntries (LinuxProcessList.c:2079)
by 0x12A79A: ProcessList_scan (ProcessList.c:627)
by 0x11CA67: CommandLine_run (CommandLine.c:357)
by 0x4A81E49: (below main) (libc-start.c:314)
Uninitialised value was created by a heap allocation
at 0x48396C5: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x12F633: xRealloc (XUtils.c:64)
by 0x12F633: xReallocArray (XUtils.c:78)
by 0x1325A8: LinuxProcessList_updateCPUcount (LinuxProcessList.c:207)
by 0x134E0A: ProcessList_new (LinuxProcessList.c:284)
by 0x11C8D0: CommandLine_run (CommandLine.c:301)
by 0x4A81E49: (below main) (libc-start.c:314)
Use the same width for each sub meter to align with CPU meter.
Currently if the total width is even, so it does not split exactly into
2 equal parts plus 1 (for the middle space character column), the extra
column is added to the second meter width.
Closes: #783
Affinity.c:67:10: runtime error: implicit conversion from type 'int' of value -1 (32-bit, signed) to type 'unsigned int' changed the value to 4294967295 (32-bit, unsigned)
The build time configuration ancient-vserver implies the configuration
vserver; say so in the configure status report if only ancient-vserver
has been specified.
Also indent with 3 spaces.
In case the executable is an empty string, e.g. if pcp is run by an
unprivileged user, do not set procExe to an empty value, which breaks
the formatting of the PROCEXE column and the merged-cmdline logic.
Generalize sub-diskname handling, like sdb1/sdb2, to not count the
usage twice with the aggregate top-diskname, like sdb.
Rely on /proc/diskstats being ordered, e.g. no sub-diskname precedes its
top-diskname.
Closes: #675
If htop is started for the first time and no configuration file exists
the header is empty cause no meters are added as a default.
Add the default meters if parsing all available configuration paths
failed.
Use the color gray, similar to other process fields, if the delay
accounting value is either 0 (or very small) or cannot be accessed, e.g.
by an unprivileged user.
Drop explicit CFLAGS specification as `-Wno-c11-extensions` is enabled
on FreeBSD by the configure script.
Run and check `make install` and `make installcheck`.
The Portable Linux Processor Affinity (PLPA) project has been depreciated in
favour of the Portable Hardware Locality (hwloc) project. So the license
exception present in previous versions of htop is obsolete and thus removed.
The text of COPYING has been updated to the latest upstream license text
of GPL-2 from the Free Software Foundation, Inc. (FSF).
There are only editorial changes like line wrapping, removing page breaks,
updating the "19yy" to "<year>" and changing the FSF address.
configure.ac:72: warning: The macro `AC_PROG_CC_C99' is obsolete.
configure.ac:72: You should run autoupdate.
./lib/autoconf/c.m4:1659: AC_PROG_CC_C99 is expanded from...
configure.ac:72: the top level
configure.ac:134: warning: The macro `AC_HEADER_STDC' is obsolete.
configure.ac:134: You should run autoupdate.
./lib/autoconf/headers.m4:704: AC_HEADER_STDC is expanded from...
configure.ac:134: the top level
The function strcasestr(3) is only available if _GNU_SOURCE is defined.
If any file includes <string.h> before declaring _GNU_SOURCE, e.g by
including "config.h", compilation fails with the following error:
In file included from ColumnsPanel.c:8:
In file included from ./ColumnsPanel.h:12:
In file included from ./Panel.h:13:
In file included from ./CRT.h:16:
In file included from ./Settings.h:17:
In file included from ./Process.h:15:
In file included from ./Object.h:17:
./XUtils.h:42:11: error: implicit declaration of function 'strcasestr' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
return strcasestr(s1, s2) != NULL;
^
./XUtils.h:42:11: note: did you mean 'strcasecmp'?
/usr/include/strings.h:116:12: note: 'strcasecmp' declared here
extern int strcasecmp (const char *__s1, const char *__s2)
^
Move the implementation to avoid unnecessary includes.
Since LTO is quite common and stable performance should not be impacted
if used.
Use a name in the user configuration file instead of the compile
time enum value, so that future reorderings or insertions do not change
the user selected layout.
Meter.c:320:71: warning: performing an implicit widening conversion to type '__suseconds_t' (aka 'long') of a multiplication performed in type 'int' [bugprone-implicit- widening-of-multiplication-result]
struct timeval delay = { .tv_sec = globalDelay / 10, .tv_usec = (globalDelay - ((globalDelay / 10) * 10)) * 100000 };
^
Found by clang-tidy.
home/christian/Coding/workspaces/htop/Process.c:505:13: warning: 'continue' in loop with false condition is equivalent to 'break' [bugprone-terminating-continue]
WRITE_HIGHLIGHT(0, strlen(procComm), commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM);
^
/home/christian/Coding/workspaces/htop/Process.c:461:13: note: expanded from macro 'WRITE_HIGHLIGHT'
continue; \
^
The main change is the header hight being not included in y1.
This is important if a sub-manager gets resized, e.g. a resize while
editing the Settings or in a pickFromVector selection, and afterwards,
then the sub-manager is closed, the super-ScreenManager gets resized, it
uses the correct header hight.
The header hight might have been changed since the last resize of the
super-manager in the Settings by adding/removing some meters.
This fixes new meters being hidden after added at runtime after a resize
in the main window.
This cannot be negative in these code locations, but for the
purposes of static checking like Coverity scan make it clear
and used the same unsigned type as ProcessList.h for the CPU
count variable (matching PL activeCPUs and existingCPUs).
This cannot happen in these code locations, but for the purposes
of static checkers like Coverity scan (and for future proofing),
add two more guards on NULL hash table entry pointers.
The signal handler will access the Settings struct, which gets freed at
normal program finalization.
When using leak sanitizers with ASAN_OPTIONS=abort_on_error=1, which
runs after program termination, any leak causes SIGABRT to be raised,
calling the crash handler, which will derefernce the freed Settings.
==44741==ERROR: AddressSanitizer: heap-use-after-free on address 0x60d000000080 at pc 0x0000005680df bp 0x7fffe335e960 sp 0x7fffe335e958
READ of size 8 at 0x60d000000080 thread T0
#0 0x5680de in Settings_write /home/christian/Coding/workspaces/htop/Settings.c:329:26
#1 0x4f77b7 in CRT_handleSIGSEGV /home/christian/Coding/workspaces/htop/CRT.c:1020:4
#2 0x7f8a1120c13f (/lib/x86_64-linux-gnu/libpthread.so.0+0x1413f)
#3 0x7f8a11042ce0 in __libc_signal_restore_set signal/../sysdeps/unix/sysv/linux/internal-signals.h:86:3
#4 0x7f8a11042ce0 in raise signal/../sysdeps/unix/sysv/linux/raise.c:48:3
#5 0x7f8a1102c536 in abort stdlib/abort.c:79:7
#6 0x4c3db6 in __sanitizer::Abort() (/home/christian/Coding/workspaces/htop/htop+0x4c3db6)
#7 0x4c2090 in __sanitizer::Die() (/home/christian/Coding/workspaces/htop/htop+0x4c2090)
#8 0x4d0a17 in __lsan::HandleLeaks() (/home/christian/Coding/workspaces/htop/htop+0x4d0a17)
#9 0x4cd950 in __lsan::DoLeakCheck() (/home/christian/Coding/workspaces/htop/htop+0x4cd950)
#10 0x7f8a110454d6 in __run_exit_handlers stdlib/exit.c:108:8
#11 0x7f8a11045679 in exit stdlib/exit.c:139:3
#12 0x7f8a1102dd10 in __libc_start_main csu/../csu/libc-start.c:342:3
#13 0x428a19 in _start (/home/christian/Coding/workspaces/htop/htop+0x428a19)
0x60d000000080 is located 64 bytes inside of 144-byte region [0x60d000000040,0x60d0000000d0)
freed by thread T0 here:
#0 0x4a4f72 in free (/home/christian/Coding/workspaces/htop/htop+0x4a4f72)
#1 0x566693 in Settings_delete /home/christian/Coding/workspaces/htop/Settings.c:32:4
#2 0x4ede10 in CommandLine_run /home/christian/Coding/workspaces/htop/CommandLine.c:393:4
#3 0x4d6f32 in main /home/christian/Coding/workspaces/htop/htop.c:15:11
#4 0x7f8a1102dd09 in __libc_start_main csu/../csu/libc-start.c:308:16
previously allocated by thread T0 here:
#0 0x4a5372 in __interceptor_calloc (/home/christian/Coding/workspaces/htop/htop+0x4a5372)
#1 0x57f61a in xCalloc /home/christian/Coding/workspaces/htop/XUtils.c:55:17
#2 0x5688a6 in Settings_new /home/christian/Coding/workspaces/htop/Settings.c:392:21
#3 0x4ecb57 in CommandLine_run /home/christian/Coding/workspaces/htop/CommandLine.c:303:25
#4 0x4d6f32 in main /home/christian/Coding/workspaces/htop/htop.c:15:11
#5 0x7f8a1102dd09 in __libc_start_main csu/../csu/libc-start.c:308:16
SUMMARY: AddressSanitizer: heap-use-after-free /home/christian/Coding/workspaces/htop/Settings.c:329:26 in Settings_write
Querying kernel threads with `ps -o pid,lid,flags,state,lname -sp 0`
gives that kernel threads have state `K` and flags have mask `0x20000` set.
This corresponds to `LW_SYSTEM` in kernel which is mapped as `L_SYSTEM`/`P_SYSTEM` for userspace.
Update merged command-line when started with "Show custom thread names"
disabled and enabling at runtime.
Also only consider showThreadNames when working on userland threads.
Implements support for arbitrary Performance Co-Pilot
metrics with per-process instance domains to form new
htop columns. The column-to-metric mappings are setup
using configuration files which will be documented via
man pages as part of a follow-up commit.
We provide an initial set of column configurations so
as to provide new capabilities to pcp-htop: including
configs for containers, open fd counts, scheduler run
queue time, tcp/udp bytes/calls sent/recv, delay acct,
virtual machine guests, detailed virtual memory, swap.
Note there is a change to the configuration file path
resolution algorithm introduced for 'dynamic meters'.
First, look in any custom PCP_HTOP_DIR location. Then
iterate, in priority order, users home directory, then
local sysadmins files in /etc/pcp/htop, then readonly
configuration files below /usr/share/pcp/htop. This
final location becomes the preferred place for our own
shipped meter and column files.
The Settings file (htoprc) writing code is updated to
not using the numeric identifier for dynamic columns.
The same strategy used for dynamic meters is used here
where we write Dynamic(name) so the name can be setup
once more at start. Regular (static) columns writing
to htoprc - i.e. numerically indexed - is unchanged.
Adds AGRP (autogroup) and ANI (autogroup nice) columns that
report the information from /proc/PID/autogroup, as well as
handlers for '{' and '}' to change the autogroup nice value.
This is guarded by /proc/sys/kernel/sched_autogroup_enabled
such that sampling and/or changing values wont be attempted
unless the kernel feature is enabled.
Fixes: #720
Compilers might due to optimizations, like -ffast-math (included in
-Ofast) expect floating point variables to be never NaN and replace each
call to isnan() with false. Htop uses the value NaN for signaling no
data available for various information.
Warn at configure time if the compiler will ignore NaN values.
Note: this can not be implemented as a compile time static assert, as
some compilers handle compile NaNs differently than runtime NaNs.
This uses proplib and sysmon_envsys to determine the total charge
percentage of any number of connected batteries as well as the
AC adapter state. Should work with ACPI and non-ACPI systems.
Add some words about pcp-htop to the main man page, and add a
new man page describing the pcp-htop configuration files that
allow new meters and columns to be defined at runtime.
Default settings are used as a base and only settings specified in `htoprc` are
applied on top of it. This patch removes the special case for applying some
defaults when the config does not contain a `meters` key. All defauls are set
before any attempt to read settings, so only keys actually present in the config
file are overridden.
This makes the behaviour consistent with other platforms where AC is
marked as present if at least one power source is marked as AC_PRESENT.
Fixes: #711
openbsd/OpenBSDProcessList.c:176:56: error: no member named 'ki_pid' in 'struct kinfo_proc'; did you mean 'p_pid'?
const int mib[] = { CTL_KERN, KERN_PROC_CWD, kproc->ki_pid };
^~~~~~
p_pid
/usr/include/sys/sysctl.h:375:10: note: 'p_pid' declared here
int32_t p_pid; /* PID_T: Process identifier. */
^
openbsd/OpenBSDProcessList.c:458:33: error: comparison of integers of different signs: 'int' and 'unsigned int' [-Werror,-Wsign-compare]
if (opl->cpus[i].cpuIndex == id)
~~~~~~~~~~~~~~~~~~~~~ ^ ~~
Currently htop does not support offline CPUs and hot-swapping, e.g. via
echo 0 > /sys/devices/system/cpu/cpu2/online
Split the current single cpuCount variable into activeCPUs and
existingCPUs.
Supersedes: #650
Related: #580
This adds a configure check for the ncurses getmouse() function
and disables mouse-related code paths when mouse support is
not present in the curses library.
This is necessary for stable versions of NetBSD's libcurses, the
development version has stub mouse functions for compatibility
with ncurses.
Signed-off-by: Nia Alarie <nia@NetBSD.org>
Before this change, the systemd meter was broken on distros like NixOS,
which have systemctl in PATH, but not at /bin/systemctl. After the
change, it works on all my NixOS machines.
It can happen that pcp-htop is presented multiple definitions
of the same dynamic meter, e.g. if /etc/pcp/htop/meters has a
definition matching one in ~/.config/htop/meters - instead of
exiting with a duplicate metric error provide more meaningful
diagnostics (on close) and also just skip over such entries.
System files override home directories which overrides those
found below the current working directory.
Also fix the derived metric error diagnostic; because this is
using CRT_fatalError, which is like perror(3), we must give a
meaningful prefix (like program name) at the string end.
This SIGINT handler is installed on top of an optional
handler that some curses/ncurses implementations provide.
This ensures the curser is properly reset when hitting Ctrl+C.
Right now Unicode support must be disabled, because htop peeks
into the ncurses cchar_t struct with Unicode enabled. NetBSD's cchar_t
has different contents.
Partially fixes#660
Signed-off-by: Nia Alarie <nia@NetBSD.org>
Several improvements to the way values are displayed in the
PCP platform DynamicMeter implementation:
- handle the initial 'caption' setting as with regular meters,
this required a new meter callback because we no longer have
just a single meter caption for the DynamicMeter case
- if no label is provided for a metric in a configuration file
use the short form metric name as a fallback
- honour the suffix setting in the configuration file
- convert metric values to the canonical units for htop (kbyte
and seconds), and use Meter_humanUnit when it makes sense to
do so.
Also improves the handling of fatal string error messages in a
couple of places, thanks to BenBE for the review feedback.
This commit is based on exploratory work by Sohaib Mohamed.
The end goal is two-fold - to support addition of Meters we
build via configuration files for both the PCP platform and
for scripts ( https://github.com/htop-dev/htop/issues/526 )
Here, we focus on generic code and the PCP support. A new
class DynamicMeter is introduced - it uses the special case
'param' field handling that previously was used only by the
CPUMeter, such that every runtime-configured Meter is given
a unique identifier. Unlike with the CPUMeter this is used
internally only. When reading/writing to htoprc instead of
CPU(N) - where N is an integer param (CPU number) - we use
the string name for each meter. For example, if we have a
configuration for a DynamicMeter for some Redis metrics, we
might read and write "Dynamic(redis)". This identifier is
subsequently matched (back) up to the configuration file so
we're able to re-create arbitrary user configurations.
The PCP platform configuration file format is fairly simple.
We expand configs from several directories, including the
users homedir alongside htoprc (below htop/meters/) and also
/etc/pcp/htop/meters. The format will be described via a
new pcp-htop(5) man page, but its basically ini-style and
each Meter has one or more metric expressions associated, as
well as specifications for labels, color and so on via a dot
separated notation for individual metrics within the Meter.
A few initial sample configuration files are provided below
./pcp/meters that give the general idea. The PCP "derived"
metric specification - see pmRegisterDerived(3) - is used
as the syntax for specifying metrics in PCP DynamicMeters.
When manipulating CPUMeters in the AvailableMeterPanel we
use the bottom 16 bits to hold the CPU number. However,
the bitmask used to extract the CPU number only masks the
lower 8 bits (0xff).
Allow other projects (PCP) to be able to ship an htop binary
which uses the custom name (pcp-htop) in several diagnostics
so that its clear which (if any!) binary failed.
Reading and parsing /proc/<pid>/maps is quite expensive.
Do not check for deleted libraries if the main binary has been deleted;
in this case the deleted binary takes precedence.
Do not check in threads. The check is void for kernel threads and user-
land threads can just inherit the state from the main process structure.
O_PATH is available since Linux 2.6.39, but we are using fstat(2) on the
returned file descriptor in LinuxProcessList_statProcessDir(), which
is only supported since Linux 3.6.
Fixes#534
Shared libraries can be replaced by an upgrade, highlight processes
using deleted shared libraries.
Link with highlightDeletedExe setting, enabled by default.
Currently only checked on Linux.
Remove code now that we have common platform-independent command
line wrangling (thanks BenBE!). Add PCP platform support for a
handful of other recently arriving odds and ends - ELAPSED time,
CWD, and so on.
Updates for recent NetworkIO Meter changes, adds support
for the SysArch and HostName Meters. The SysArch change
is based on work originally by Sohaib Mohamed.
This introduces an initial platform for extracting metrics
using the PCP performance metrics API - PMAPI(3). It can
be used via the --enable-pcp=yes configure option.
So far I've added support for live localhost metrics only,
and only using pre-defined metrics already found in htop.
If available, all sampling is performed by pmcd(1) - else,
we fallback to htop doing the metric sampling itself (all
below the PMAPI). When pmcd is used, it may be configured
to run children with elevated privileges, so htop does not
need to be setuid (authentication with pmcd is available).
Additionally, the PMAPI allows us to support archives (for
historical analysis and for automated regression tests in
htop). We'll need platform-specific command line argument
additions, which isn't yet feasible in htop (not difficult
to add though).
The goal of this first version is minimal impact in terms
of modifying the htop codebase, to introduce key ideas in
PCP (metric namespace, metadata, APIs and so on) and give
us something to discuss, experiment with and build on.
Add process columns showing the elapsed time since the process was
started.
Similar to STARTTIME, but shows the time passed since the process start
instead of the fixed start time of the process.
Closes https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=782636
The following assert failure might happen on short running threads with
an empty comm value in /proc/${pid}/stat:
htop: Process.c:1159: void Process_updateCmdline(Process *, const char *, int, int): Assertion `(cmdline && basenameStart < (int)strlen(cmdline)) || (!cmdline && basenameStart == 0)' failed.
The specific task is:
comm=''
exe='(null)'
cmdline='/usr/bin/ruby /usr/bin/how-can-i-help --apt'
So basenameStart is 0, while strlen(cmdline) is also 0.
On OmniOS /usr/include/sys/regset.h redefines ERR to 13 - \r, breaking
the Enter key.
Since ncruses macros use the ERR macro, we can not use another name.
Closes: #634
- fill tty name
- fill session id
- show real tgid not adjusted
- drop unimplemented TPGID, MINFLT and MAJFLT
- adjust header width of ZONEID, which get auto-adjusted as a pid-column
The system interfaces kstat_lookup() and kstat_data_lookup() take a
non-constant string parameter, but passing string literals is valid.
Add wrapper functions to ignore all the const-discard warnings.
If pkg-config is not installed the following message gets printed, even
on non Linux platform:
"Linux delay accounting support can not be enabled, cause pkg-config is
required for checking its availability"
- fix header width of IO_READ_RATE
- save data in bytes (not kilobytes) to better compute rate
- fix rate data: multiply with 1000 to compensate time difference in
milliseconds
- rename unit less variable now into realtimeMs
- use Process_printBytes(..., data * pageSize, ...) instead of
Process_printKBytes(..., data * pageSizeKB, ...) to avoid wrapper
Make functions formatting data for a process field column less error
prone, unify interfaces and improve some internals.
* Process_printBytes
- rename from Process_humanNumber
- take number in bytes, not kilobytes
- handle petabytes
- increase buffer to avoid crashes when the passed value is
~ ULLONG_MAX
* Process_printKBytes
- add wrapper for Process_printBytes taking kilobytes keeping -1 as
special value
* Process_printCount
- rename from Process_colorNumber
* Process_printTime
- add coloring parameter as other print functions
- improve coloring and formatting for larger times
* Process_printRate
- rename from Process_outputRate
- use local buffer instead of passed one; this function prints to the
RichString after all
`RichString_appendWide()` is more expensive than
`RichString_appendAscii()` due to the calls to `mbstowcs(3)` and
`iswprint(3)`.
Use the latter to print the process field buffer by default.
For the following fields this theoretically can corrupt the output:
- SECATTR
- CGROUP
- CTID
`RichString_appendWide()` is more expensive than
`RichString_appendAscii()` due to the calls to `mbstowcs(3)` and
`iswprint(3)`.
Use the latter to print the process field buffer by default.
For the following fields this theoretically can corrupt the output:
- TTY
`RichString_appendnAscii()` avoids a `strlen(3)` call over
` RichString_appendAscii()`.
Use the former where the length is available from a previous checked
`snprintf(3)` call.
Keep `RichString_appendAscii()` when passing a string literal and
rely on compilers to optimize the `strlen(3)` call away.
By default, OpenBSD disables SMT (hyperthreading) cpu pseudo-cores.
This can be changed at runtime by setting the hw.smt sysctl so they
may become active later, therefore they are still present in cpu
stat structures but are marked as offline.
As done with native top(1), this drops them from the cpu summary
graphs.
Compat.c: In function 'Compat_faccessat':
Compat.c:46:14: error: comparison of integer expressions of different signedness: 'int' and 'unsigned int' [-Werror=sign-compare]
46 | if (dirfd != AT_FDCWD || mode != F_OK) {
| ^~
freebsd/FreeBSDProcessList.c:252:47: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'unsigned int'
#0 0x397c32 in FreeBSDProcessList_scanCPU /root/workspace/htop/htop/freebsd/FreeBSDProcessList.c:252:47
#1 0x38fe76 in ProcessList_goThroughEntries /root/workspace/htop/htop/freebsd/FreeBSDProcessList.c:438:4
#2 0x35ef9a in ProcessList_scan /root/workspace/htop/htop/ProcessList.c:618:4
#3 0x31ee9e in main /root/workspace/htop/htop/htop.c:468:4
#4 0x26bbcf in _start /usr/src/lib/csu/amd64/crt1.c:76:7
* Rename internal identifier from TTY_NR to just TTY
* Unify column header on platforms
* Use devname(3) on BSD derivate to show the actual terminal,
simplifies current FreeBSD implementation.
* Use 'unsigned long int' as id type, to fit dev_t on Linux.
Only on Solaris the terminal path is not yet resolved.
Refactor the sample time code to make one call to gettimeofday
(aka the realtime clock in clock_gettime, when available) and
one to the monotonic clock. Stores each in more appropriately
named ProcessList fields for ready access when needed. Every
platform gets the opportunity to provide their own clock code,
and the existing Mac OS X specific code is moved below darwin
instead of in Compat.
A couple of leftover time(2) calls are converted to use these
ProcessList fields as well, instead of yet again sampling the
system clock.
Related to https://github.com/htop-dev/htop/pull/574
The end goal is to consolidate all the points in htop that can only work in
live-only mode today, so that will be able to inject PCP archive mode and have
a chance at it working.
The biggest problem we've got at this moment is all the places that are
independently asking the kernel to 'give me the time right now'.
Each of those needs to be audited and ultimately changed to allow platforms to
manage their own idea of time.
So, all the calls to gettimeofday(2) and time(2) are potential problems.
Ultimately I want to get these down to just one or two.
Related to https://github.com/htop-dev/htop/pull/574
BenBE points out that some header meters use values calculated
during process scanning - make sure we scan processes first in
order that current values are displayed.
Related to https://github.com/htop-dev/htop/pull/574
Always show the number of kernel and userland threads, even when they
are disabled to not be shown in the process list.
The data is already available and might improve understanding the system
utilization.
Use a shadow color in case the kind of thread is hidden, else the normal
meter one.
One review request relating to the PCP platform is to have
a clearly separate binary from the regular htop so that we
have no confusion as to what is being requested to run, to
aid debugging, and a bunch of other good reasons.
This commit renames htop.c to CommandLine.c and provides a
minimal htop main function for 'native' platforms to use.
The PCP version of this will setup libpcp.so and then call
the same CommandLine_run function as regular htop.
Related to https://github.com/htop-dev/htop/pull/536
Follow up on the two items of feedback from cgzones review,
and resolve a build failure picked up by CI on Mac OS X.
Related to https://github.com/htop-dev/htop/pull/564
The libcap code is Linux-specific so move it all below
the linux/ platform subdirectory. As this feature has
custom command-line long options I provide a mechanism
whereby each platform can add custom long options that
augment the main htop options. We'll make use this of
this with the pcp/ platform in due course to implement
the --host and --archive options there.
Related to https://github.com/htop-dev/htop/pull/536
This prefers the `#if defined()` syntax over the `#ifdef` variant
whenever there's also a `#elif defined()` clause, thus making the
multiple branching structure more obvious and the overall use
more consistent.
* Set process data for:
- minflt
- majflt
- processor
- nlwp
* Drop unimplemented nlwp column
* Scan userland threads
* Mark a 'Thread is currently on a CPU.' with 'R', and processes
'Currently runnable' with 'P', do confine with man:ps(1) and Linux.
See https://man.openbsd.org/ps.1
* Show CPU frequency
Currently the tree-view is empty on OpenBSD when kernel threads are
hidden, cause the kernel thread 'swapper' has pid 0 and gets treated as
root of the tree and parent of 'init'.
Do not build any tree with a pid 0 root node.
Do not read driver depended labels, just count the number of
temperatures given:
on #CPU:
platform temp = max cpu temp
CPU temps = first to last
on #CPU + 1:
platform temp = first temp
CPU temps = second to last
on #CPU / 2:
platform temp = max cpu temp
CPU temps = first to last concat first to last
(with SMT core x + cpu count is the logical core of the physical
core x)
on #CPU / 2 + 1:
platform temp = first temp
CPU temps = second to last concat second to last
(with SMT core x + cpu count is the logical core of the physical
core x)
Closes: #529Closes: #538
The hwloc header generates lots of warnings:
In file included from Action.c:10:
In file included from ./Action.h:15:
In file included from ./Header.h:10:
In file included from ./Meter.h:18:
In file included from ./ProcessList.h:25:
In file included from /usr/include/hwloc.h:2371:
/usr/include/hwloc/helper.h:481:5: warning: Value stored to 'state' is never read [deadcode.DeadStores]
state = 3;
^ ~
1 warning generated.
The local stack buffer does not need to be cleaned to zeros when
- just initialized, cause the length is set to 0 and the first
character is set to '\0', so all printing functions will safely stop
- no further used, i.e. the variable goes out of scope
- stay in follow mode on sort inversion (I)
- stay in follow mode after viewing help screen (h)
- select parent process (where available) when having followed a thread
and hiding these (H)
Closes: #560
Combine reading CPU count and CPU usage, only open the file once.
Do not separately initialize totalPeriod and totalTime, cause the value
0 is handled in Platform_setCPUValues().
Take the number of currently running process from the entry
procs_running in /proc/stat instead of counting all scanned process
with state 'R', to include hidden tasks, e.g. threads.
Writing to the file stream might fail due to a immutable file or a
filesystem error.
Check the error indicator for the stream and for fclose() failures.
Code that is shared across some (but not all) platforms
is moved into a 'generic' home. Makefile.am cleanups to
match plus some minor alphabetic reordering/formatting.
As discussed in https://github.com/htop-dev/htop/pull/553
Several of our newer meters have merged coding concerns in terms
of extracting values and displaying those values. This commit
rectifies that for the SysArch and Hostname meters, allowing use
of this code with alternative front/back ends. The SysArch code
is also refined to detect whether the platform has an os-release
file at all and/or the sys/utsname.h header via configure.ac.
On Linux kernels the size of the values exported for block
device bytes has used a 64 bit integer for quite some time
(2.6+ IIRC). Make the procfs value extraction use correct
types and change internal types used to rate convert these
counters (within the DiskIO Meter) 64 bit integers, where
appropriate.
On Linux kernels the size of the values exported for network
device bytes and packets has used a 64 bit integer for quite
some time (2.6+ IIRC). Make the procfs value extraction use
correct types and change internal types used to rate convert
these counters (within the NetworkIO Meter) 64 bit integers,
where appropriate.
This support was rarely ever used and has been disabled by default for some time.
As far as the developer team is aware there's no distribution that activated this
feature in their packages by default.
os-release is available on FreeBSD by default.
Also avoid executing a third-party program.
Examples:
Linux 5.10.0-3-amd64 [x86_64] @ Debian GNU/Linux bullseye/sid
FreeBSD 12.2-RELEASE-p3 [amd64]
Closes: #516
`ZFS_RATIO` in `CRT.c` was unused, because I forgot
to colorize the ARC ratio in the Compressed ARC meter.
The intent was to improve readability of the meter by
highlighting the most relevant value, the ratio, in
a brighter color, for most themes. This change effects
that intent.
* Use MemAvailable info from Linux 3.14+ where available
* Thanks to Chris Cheney for reporting and Tomas Wido for an initial implementation
Closes#281Closes#385
Use similar calculation than procps.
Show AvailableMemory in text mode.
Use total minus available memory instead of manually computed used-
memory as fraction part in bar mode (if available).
The State struct holds a pointer to the main process panel.
Use the distinct MainPanel type, to improve maintainability regrading
its usage.
This avoids usages of down-casts from Panel to MainPanel, only up-casts
from MainPanel to Panel are now required.
Unavailable values are returned as "n/a" from lsb_release, skip these.
$ lsb_release -a
LSB Version: 1.4
Distributor ID: Arch
Description: Arch Linux
Release: rolling
Codename: n/a
As SYSCONFDIR is a compile time string literal, use compile time string
concatenation instead of a runtime one.
Also drop related TODO, cause we indeed using the correct way of getting
$sysconfdir from autoconf
If the last process entry is selected and the process dies, stay at the
end of the list and do not jump to the start.
Also if the last entry is selected keep, after rebuilding the process
list due to a new scan, the last entry selected.
At start, SysArchMeter calls the uname function to obtain the kernel
version and architecture. If available, the distro version is obtained
by calling lsb_release. The obtained values are stored in static
variables and used when updating the meter.
pgrp and session might be -1
linux/LinuxProcessList.c:312:20: runtime error: implicit conversion from type 'unsigned long' of value 18446744073709551615 (64-bit, unsigned) to type 'unsigned int' changed the value to 4294967295 (32-bit, unsigned)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior linux/LinuxProcessList.c:312:20 in
linux/LinuxProcessList.c:314:23: runtime error: implicit conversion from type 'unsigned long' of value 18446744073709551615 (64-bit, unsigned) to type 'unsigned int' changed the value to 4294967295 (32-bit, unsigned)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior linux/LinuxProcessList.c:314:23 in
- avoid UBSAN conversions
- print N/A on no data (i.e. as unprivileged user)
- fix rate calculation to show bytes (instead of a thousandth)
- print bytes as human number (i.e. 8MB) instead of 8388608
- stabilize sorting by adjusting NAN values to very tiny negative number
- sort cases by identifier
- use check snprintf
- color nice value of 0 as gray
- color cpu and memory percentages of 0.0 as gray
- color number of threads of 1 as gray
- color idle and sleeping state as gray
- color tgid matching pid (indicating main thread) as gray
If no terminal name can be found, fall back to generic display method
with major and minor device numbers.
Print special value '(none)' in case both are zero.
Using the same function for the same library causes AC_CHECK_LIB to use
cached results.
Since we change the detection method via different or no
ncurses(5|6)-config invocation, avoid such caching by using different
functions.
- require autoconf version 2.69
was released in 2012 and one still can configure and build on older
systems (just not generate the configure script)
- use modern C99 compiler check
- drop obsolete checks: AC_C_CONST, AC_FUNC_CLOSEDIR_VOID, AC_FUNC_STAT
- drop AC_HEADER_STDBOOL in favor of C99 compatibility
On some AMD and Intel CPUs read()ing scaling_cur_freq is quite slow
(> 1ms). This delay accumulates for every core.
If the read on CPU 0 takes longer than 500us bail out and fall back to
reading the frequencies from /proc/cpuinfo.
Once the condition has been met, bail out early for the next couple of
scans.
Closes: #471
Print wide characters, like degree sign, properly via mvadd_wch().
Ignore attributes when returning value from RichString_getCharVal() in
non-wide ncurses mode to test against raw characters.
strcasestr(3) is a GNU extension and when compiling freebsd/Platform.c
on kfreebsd for Debian <string.h> is included before we define
_GNU_SOURCE, so the function is not available.
In file included from ./Object.h:16,
from ./ListItem.h:12,
from ./Meter.h:16,
from ./Header.h:10,
from ./Action.h:15,
from freebsd/Platform.h:13,
from freebsd/Platform.c:8:
./XUtils.h: In function ‘String_contains_i’:
./XUtils.h:43:11: warning: implicit declaration of function ‘strcasestr’; did you mean ‘strcasecmp’? [-Wimplicit-function-declaration]
43 | return strcasestr(s1, s2) != NULL;
| ^~~~~~~~~~
| strcasecmp
./XUtils.h:43:30: warning: comparison between pointer and integer
43 | return strcasestr(s1, s2) != NULL;
| ^~
In file included from ./Object.h:16,
from ./ProcessList.h:16,
from freebsd/FreeBSDProcessList.h:15,
from freebsd/FreeBSDProcessList.c:8:
./XUtils.h: In function ‘String_contains_i’:
./XUtils.h:43:11: warning: implicit declaration of function ‘strcasestr’; did you mean ‘strcasecmp’? [-Wimplicit-function-declaration]
43 | return strcasestr(s1, s2) != NULL;
| ^~~~~~~~~~
| strcasecmp
./XUtils.h:43:30: warning: comparison between pointer and integer
43 | return strcasestr(s1, s2) != NULL;
| ^~
strcasestr(3) is a GNU extension and when compiling freebsd/Platform.c
on kfreebsd for Debian <string.h> is included before we define
_GNU_SOURCE, so the function is not available.
In file included from ./Object.h:16,
from ./ListItem.h:12,
from ./Meter.h:16,
from ./Header.h:10,
from ./Action.h:15,
from freebsd/Platform.h:13,
from freebsd/Platform.c:8:
./XUtils.h: In function ‘String_contains_i’:
./XUtils.h:43:11: warning: implicit declaration of function ‘strcasestr’; did you mean ‘strcasecmp’? [-Wimplicit-function-declaration]
43 | return strcasestr(s1, s2) != NULL;
| ^~~~~~~~~~
| strcasecmp
./XUtils.h:43:30: warning: comparison between pointer and integer
43 | return strcasestr(s1, s2) != NULL;
| ^~
In file included from ./Object.h:16,
from ./ProcessList.h:16,
from freebsd/FreeBSDProcessList.h:15,
from freebsd/FreeBSDProcessList.c:8:
./XUtils.h: In function ‘String_contains_i’:
./XUtils.h:43:11: warning: implicit declaration of function ‘strcasestr’; did you mean ‘strcasecmp’? [-Wimplicit-function-declaration]
43 | return strcasestr(s1, s2) != NULL;
| ^~~~~~~~~~
| strcasecmp
./XUtils.h:43:30: warning: comparison between pointer and integer
43 | return strcasestr(s1, s2) != NULL;
| ^~
According to the Linux kernel documentation, "SwapCached" tracks "memory
that once was swapped out, is swapped back in but still also is
in the swapfile (if memory is needed it doesn't need to be swapped out
AGAIN because it is already in the swapfile. This saves I/O)."
It is only used on Linux to optimize memory handling in case the command
changes to a smaller-or-equal string.
This "optimization" however causes more code bloat and maintenance cost
on string handling issues than it gains.
CRT.c:821:2: error: embedding a directive within macro arguments has undefined behavior [-Werror,-Wembedded-directive]
#ifdef HAVE_EXECINFO_H
^
CRT.c:823:2: error: embedding a directive within macro arguments has undefined behavior [-Werror,-Wembedded-directive]
#endif
^
CRT.c:858:2: error: embedding a directive within macro arguments has undefined behavior [-Werror,-Wembedded-directive]
#ifdef HTOP_DARWIN
^
CRT.c:862:2: error: embedding a directive within macro arguments has undefined behavior [-Werror,-Wembedded-directive]
#endif
^
CRT.c:864:2: error: embedding a directive within macro arguments has undefined behavior [-Werror,-Wembedded-directive]
#ifdef HTOP_DARWIN
^
CRT.c:868:2: error: embedding a directive within macro arguments has undefined behavior [-Werror,-Wembedded-directive]
#endif
^
Avoid format string issues like bfcb8ca0 by helping compilers spot such
bogus usages.
Also use LTO and O3 in the full-featured gcc job, which might trigger
additional warnings on advanced inlining, like
3695cbd5d8dda27f99383437035450814463b633 and
ad3acfc847e9d54f07a0684c19181d5f4c28fee4
Partially revert 4b14ab9789eee004daab8594ac00a113c18af060
ColorPair(Black,Black) is not actually black on black, but due to
adjustments in CRT_setColors() black on default-background-color.
Thanks to V for reporting.
mvwprintw takes a format string as its fourth argument, and title is
user-controlled. This results in e.g. crashing when trying to trace a
process with a format specifier in its command line.
Support three settings:
- Always show Function Bar
- Always hide the Function Bar, except in Infoscreens (Env/Locks...)
and when editing the search and filter mode
- Hide the Function Bar on ESC until the next user input
Closes: #439
The hight of a Panel dpends on whether the Panel has a header or not.
Also the header migth not be set on Panel creation, like in the
MainPanel. This currently causes the cursor to get hidden behind the
FunctionBar on down-scrolling.
Change the color and total based on the actual 1min load value:
< 1 : green and total of 1.0
< cpu-count : yellow and total of cpu-count
else : red and total of 2*cpu-count
Closes: #32
Draw the FunctionBar within Panel_draw instead of manually throughout
the code.
Add an optional PanelClass function drawFunctionBar, to allow specific
panels to override the default FunctionBar_draw call.
Rework the code on color change, to really change all colors (selection
markers and panel headers).
Closes: #402
In case the text is too long for the bar, try to fit by truncating at a
space character.
E.g.
[|24.1% 2000Mhz 40°C]
[24.1% 2000Mhz 40°C]
[||||24.1% 2000Mhz]
[|||24.1% 2000Mhz]
[||24.1% 2000Mhz]
[|24.1% 2000Mhz]
[24.1% 2000Mhz]
[|||| 24.1%]
[|||| 24.1%]
[|||| 24.1%]
[||||24.1%]
[|||24.1%]
[||24.1%]
[|24.1%]
[24.1%]
[24.1]
[24.]
[24]
[2]
Division by 100000.0 worked because `sysconf(_SC_CLK_TCK)` happened to be 100.
By unhardcoding:
1) It becomes more clear what this 100000.0 figure comes from.
2) It protects against bugs in the case `sysconf(_SC_CLK_TCK)` ever changes.
Use only one enum instead of a global and a platform specific one.
Drop Platform_numberOfFields global variable.
Set known size of Process_fields array
This acheives two things:
- Allows for simple tie-breaking if values compare equal (needed to make sorting the tree-view stable)
- Allows for platform-dependent overriding of the sort-order for specific fields
Also fixes a small oversight on DragonFlyBSD when default-sorting.
Implements the suggestion from https://github.com/htop-dev/htop/issues/399#issuecomment-747861013
Thanks to the refactors from 0bd5c8fb5da and 6393baa74e5, this was really easy
and clean to do.
It maintains the "Tree view always by PID" option in the Settings, which
results in some specific behaviors such as "clicking on the column header to
exit tree view" and "picking a new sort order to exit tree view", for the sake
of the muscle memory of long time htop users. :)
* This removes duplicated code that adjusts the sort direction from every
OS-specific folder.
* Most fields in a regular htop screen are OS-independent, so trying
Process_compare first and only falling back to the OS-specific
compareByKey function if it's an OS-specific field makes sense.
* This will allow us to override the sortKey in a global way without having
to edit each OS-specific file.
There is a possible path - albeit theoretical really - through
the btime initialization code in Linux ProcessList_new(), when
String_startsWith() is always false, which can result in btime
not being initialized.
This commit refactors the code to remove that possibility.
Small cleanups - add error handling, remove a local static
variable and refactor LinuxProcess_adjustTime (also rename
it, as its in LinuxProcessList.c not LinuxProcess.c) - and
while there, move the related 'btime' global variable into
LinuxProcessList.c so it can be made static.
Resolves https://github.com/htop-dev/htop/issues/384
libsensors.so is provided only by the -dev package, so search for
libsensors.so.5 (installed from the libsensors5 package) explicitly
see: dpkg-query -S libsensors.so
By storing the per-process m_resident and m_virt values in the form
htop wants to display them in (KB, not pages), we no longer need to
have definitions of pageSize and pageSizeKB in the common CRT code.
These variables were never really CRT (i.e. display) related in the
first place. It turns out the darwin platform code doesn't need to
use these at all (the process values are extracted from the kernel
in bytes not pages) and the other platforms can each use their own
local pagesize variables, in more appropriate locations.
Some platforms were actually already doing this, so this change is
removing duplication of logic and variables there.
RichString_writeFrom takes a top spot during performance analysis due to the
calls to mbstowcs() and iswprint().
Most of the time we know in advance that we are only going to print regular
ASCII characters.
linux/SELinuxMeter.c: In function ‘hasSELinuxMount’:
linux/SELinuxMeter.c:38:21: warning: comparison of integer expressions of different signedness: ‘__fsword_t’ {aka ‘int’} and ‘unsigned int’ [-Wsign-compare]
38 | if (sfbuf.f_type != SELINUX_MAGIC) {
| ^~
Origin: 7df27b78e9/libselinux/src/init.c (L40)
linux/LinuxProcessList.c:1403:63: runtime error: division by zero
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior linux/LinuxProcessList.c:1403:63 in
There was wording about brace-enclosing single code statements
being 'strongly encouraged' - this isn't consistently used and
IMO it introduces unnecessary noise in otherwise neat, concise
code.
I've reworded (dropped) this section and also fixed a handful
of minor typos while reading this doc a little more carefully.
The global ProcessList structure contains a couple of unused
fields. 'sharedMem' has never been used by any Meter, since
its not been anything other than zero in Linux /proc/meminfo
for many, many years. The freeMem field is only used in the
usedMem calculation, so it can reside on the stack like some
other memory variables used within-calculations-only and not
exposed to the user via a Meter.
All calls to ScreenManager_new always pass the same first
five values, the orientation is always HORIZONTAL and the
y1 parameter is always the height of the passed-in header
struct pointer. I think its safe to assert at this point
that no VERTICAL orientation will arrive (if it does, its
no harm in re-adding this then) - so we can remove unused
conditionals (and TODOs) based on orientation too.
taskstats is only checked on runtime if the column RCHAR, WCHAR, SYSCR,
SYSCW, RBYTES, WBYTES, CNCLWB, IO_READ_RATE, IO_WRITE_RATE or IO_RATE is
selected.
taskstats is currently enabled by default.
Drop the taskstats configuration switch, to reduce the maintenance cost.
cgroup is only checked on runtime if the column CGROUP is selected.
cgroup is currently disabled by default, but most distributions do
enable it.
Drop the cgroup configuration switch, to reduce the maintenance cost.
Currently the code does not handle multi-byte characters, so length-
computations take the raw count of C characters and not the to displayed
size into account.
An example is the degree sign for temperatures.
Closes: #329
Move platform-specific code out of the htop.c main function
and into the platform sub-directories - primarily this is
the Linux procfs path check and sensors setup/teardown; not
needed on any other platforms. No functional changes here.
Dynamically increase the hashmap size to not exceed the load factor and
avoid too long chains.
Switch from Separate Chaining to Robin Hood linear probing to improve
cache locality.
Use primes as size to further avoid collisions.
E.g. on a standard kde system the number of entries in the ProcessTable
might be around 650.
If currently two unsigned values are compared via `a - b`, in the case b
is actually bigger than a, the result will not be an negative number (as
-1 is expected) but a huge positive number as the subtraction is an
unsigned subtraction.
Avoid over-/underflow affected operations; use comparisons.
Modern compilers will generate sane code, like:
xor eax, eax
cmp rdi, rsi
seta al
sbb eax, 0
ret
If the current data is smaller than the previous one, either by a retrieve error
or a device removal or a original data wraparound, sanitize the value to zero.
Fixes: #299
- Add Settings forward declaration in Process.h
- Add assert.h include in XUitls.c
- Add conditional stdbool.h include in Object.h
- Drop unneeded stddef.h include in Richstring.c
- Drop unneeded unistd.h include in Process.h
- Drop unneeded string.h include in linux/Platform.c
- Use String_eq to avoid string.h include in Action.c
- Improve script to run custom iwyu version
- allow count out-parameter of String_split() to be NULL
- introduce xStrndup()
- do not allow NULL pointers passed to String_eq()
it is not used in any code
- implement String_startsWith(), String_contains_i() and String_eq()
as inline header functions
- adjust several conversion issues
Allocating zero size memory results in implementation-defined behavior:
man:malloc(3) :
If size is 0, then malloc() returns either NULL, or a unique pointer
value that can later be successfully passed to free().
Generic data, as CPU and memory usage, are used by Meters.
In paused mode they would stop receiving updates and especially Graph
Meters would stop showing continuous data.
Improves: #214Closes: #253
man:sysconf(3) states:
The values obtained from these functions are system configuration constants.
They do not change during the lifetime of a process.
Reported by UB sanitizer (alongside several other messages):
linux/LinuxProcessList.c:782:25: runtime error: member access within misaligned address 0x614000000264 for type 'struct taskstats', which requires 8 byte alignment
0x614000000264: note: pointer points here
64 01 03 00 0a 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 4b c8 2e 00 00 00 00 00 3e 45 3c fd
^
The issue doesn't cause trouble on x86, but any architecture with stricter memory alignment requirements may inadvertedly break.
- Move swap() macro to source file and implement as function
- Implement Vector_get() and Vector_size() as inline functions
to make them type safe and avoid lhs usage
- Comment comparison statistics, they are only needed for performance
testing
- Remove local types and function from header file
- Reduce OpenFiles_Data to neccessary size
- Print file access mode (r/w/u)
- Fix memory leak on consecutive items without an intermediate file item:
==15257==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 120 byte(s) in 12 object(s) allocated from:
#0 0x48c864 in strdup (htop/htop+0x48c864)
#1 0x542f68 in xStrdup htop/XAlloc.c:71:17
#2 0x50e225 in OpenFilesScreen_getProcessData htop/OpenFilesScreen.c:112:25
#3 0x50cd17 in OpenFilesScreen_scan htop/OpenFilesScreen.c:141:35
#4 0x4fd3eb in InfoScreen_run htop/InfoScreen.c:81:35
#5 0x4d58bb in actionLsof htop/Action.c:361:4
#6 0x501766 in MainPanel_eventHandler htop/MainPanel.c:80:19
#7 0x5289fa in ScreenManager_run htop/ScreenManager.c:227:19
#8 0x4f748e in main htop/htop.c:300:4
#9 0x7ff73e0d8cc9 in __libc_start_main csu/../csu/libc-start.c:308:16
SUMMARY: AddressSanitizer: 120 byte(s) leaked in 12 allocation(s).
Doing a quick check with callgrind this gives
an average reduction from 1804 cycles/call
down to 491 cycles/call on my test system.
The average was taken over about 40k calls.
Add a date meter and sort header and source files in Makefile
Change the lists of header and source files sorted alphabetical and one
file per line. This way diffs become better readable and merges easier.
Use NDEBUG conditional instead of DEBUG.
Do not call static functions in extern inline ones.
Vector.c:67:11: error: static function 'Vector_isConsistent' is used in an inline function with external linkage [-Werror,-Wstatic-in-inline]
- do not reverse CPU steal and guest in monochrome
- black on black in Light Terminal is not visible, use blue on black
- white on blue in Light Terminal is display as blue on black, use
yellow on black
- re-draw FunctionBar after color change
When building on a 32-bit system, the compiler warned that the
following line uses a constant whose value is the overflow result
of a compile-time computation:
Process.c (line 109): } else if (number < 10000 * ONE_M) {
Namely, this constant expression:
10000 * ONE_M
was intended to produce the following value:
10485760000
However, the result overflowed to produce:
1895825408
The reason for this overflow is as follows:
o The macros are expanded:
10000 * (ONE_K * ONE_K)
10000 * (1024L * 1024L)
o The untyped constant expression "10000" is typed:
10000U * (1024L * 1024L)
o The parenthesized expression is evaluated:
10000U * (1048576L)
o The left operand ("10000U") is converted:
10000L * (1048576L)
Unbound by integer sizes, that last multiplication
would produce the following value:
10485760000
However, on a 32-bit machine, where a long is 32 bits
(really 31 bits when talking about positive numbers),
the maximum value that can be computed is 2**31-1:
2147483647
Consequently, the computation overflows.
o The compiler produces a long int value that is the
the result of overflow (10485760000 % 2**31):
1895825408L
Actually, I think this overflow is implementation-defined,
so it's not even a portable description of what happens.
The solution is to use a long long int (or, even better,
an unsigned long long int) type for the constant expression;
the C standard mandates a sufficiently large maximum value
for such types.
Hence, the following change is made to the bad line:
- } else if (number < 10000 * ONE_M) {
+ } else if (number < 10000ULL * ONE_M) {
However, the whole line is now patently silly, because the
variable "number" is typed "unsigned long", and so it will
always be less than the constant expression (the compiler
will warn about this, too).
Hence, "number" must be typed "unsigned long long"; however,
this necessitates changing all of the string formats from
something like "%lu" to something like "%llu".
Et voila! This commit is born.
Then, for the sake of completeness, the declared types of the
constant-expression macros are updated:
o ONE_K is made unsigned (a "UL" instead of "L")
o ONE_T is computed by introducing "1ULL *"
o Similar changes are made for ONE_DECIMAL_{K,T}
Also, a non-portable overflow-conversion to a signed value
has been replaced with a portable comparison:
- if ((long long) number == -1LL) {
+ if (number == ULLONG_MAX) {
It might be worth reviewing the rest of the code for other
cases where overflows are not handled correctly; even at
runtime, it's often necessary to check for overflow unless
such behavior is expected (especially for signed integer
values, for which overflow has implementation-defined
behavior).
- `CRT_fatalError()` is declared twice in CRT.h
- `Process_pidFormat`, `Process_writeField()` and `Process_compare` are
declared twice in Process.h
- `btime` is defined in LinuxProcess.c and also declared in
LinuxProcess.h, so drop in LinuxProcessList.h
This is a straightforward extension of the existing multi-column CPU meter
code, which now allows for up CPU meters to be displayed in up to 16 columns.
This also adds the meter declarations to all the platform-specific code.
Instead of scanning the meter name to determine the number of columns in a
CPU meter, move the common code behind some wrapper functions, and specify the
number of columns as an explicit parameter when called from the wrappers.
While this does add a bit of code for all the necessary wrapper functions, this
should be less brittle in case of future changes to the CPU meter code.
This commit is based on a patch originally by @edef1c. The ZFS ARC is a cache
(it's in the name), which will be evicted by the kernel if memory pressure so
requires. Hence, the ARC should not be counted towards a system's total used
memory, and should instead be grouped with the other caches in the system.
Signed-off-by: edef <edef@edef.eu>
htop.c:112:13: warning: 'break' will never be executed [-Wunreachable-code-break]
break;
^~~~~
htop.c:109:13: warning: 'break' will never be executed [-Wunreachable-code-break]
break;
^~~~~
linux/Platform.c:142:17: warning: cast from function call of type 'double' to non-matching type 'int' [-Wbad-function-cast]
return (int) floor(uptime);
^~~~~~~~~~~~~
Use the more portable sysfs node /sys/devices/system/cpu/cpuX/cpufreq/scaling_cur_freq
to get the CPU frequency.
In case of an error fall back to /proc/cpuinfo .
Also use a fixed width of 4 for the frequency to avoid position jumps
in case the frequency moves in the range 900-1100 MHz.
For a process with a very long command, especially with many long
command line arguments, inspecting the command and its arguments could
become inconvenient.
Meanwhile htop supports the concept of "screen", or window, which is
extended here to create a dedicated "CommandScreen", making it possible
to display the command of the selected process in a separate window
meanwhile being wrapped into multiple lines.
Another benefit of using a command screen is, the user can navigate
through the wrapped lines of the command and perform actions like
searching and filtering.
unsigned integer overflows are well-defined, but they might point to a counting issue.
Having the code free of unsigned overflows makes it easier to spot potential bugs.
Action.c:332:27: runtime error: implicit conversion from type 'int' of value -1 (32-bit, signed) to type 'uid_t' (aka 'unsigned int') changed the value to 4294967295 (32-bit, unsigned)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior Action.c:332:27 in
`-m` was added as short option for `--no-mouse`, this is inconsistence
to the rest of the cli since otherwise the short options to disable a
feature are capital letters. Therefore this commit renames the option to
`-M`.
This commit also documents the option in the man page.
It might be working, but lets rather not modify getopt's global variable
`optarg`.
Also there is no need to call `getenv("USER")`, just use `geteuid()`.
unsigned overflow is well defined, but creates noise when using
sanitizers. unsigned overflow can be a symptom of logic issues of
counter, so its reasonable to use.
linux/LinuxProcessList.c:64:50: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'unsigned int'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior linux/LinuxProcessList.c:64:50 in
linux/LinuxProcessList.c:64:11: runtime error: implicit conversion from type 'unsigned int' of value 4294967295 (32-bit, unsigned) to type 'int' changed the value to -1 (32-bit, signed)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior linux/LinuxProcessList.c:64:11 in
linux/LinuxProcessList.c:64:78: runtime error: unsigned integer overflow: 4 - 136 cannot be represented in type 'unsigned int'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior linux/LinuxProcessList.c:64:78 in
- enable warnings in autogen script
- drop unused m4/ directory usage
- drop AC_TYPE_SIGNAL:
C99 guarantees the signal return type to be void
- drop AC_CHECK_FILE of procdir:
most of the time compilation is done on a different system than htop is run
and there is a runtime check in place
- improve linux_affinity corss compile logic:
use fourth argument instead of pre-test
Numbering from one is idiosyncratic and inconsistent with basically
everything else in the world; it doesn't make much sense as default
behavior.
All naming is updated to reflect that numbering from one is a
non-default, opt-in option. The old label of the flag saved in htoprc
("cpu_count_from_zero") is still supported for backwards compatibility
with existing configs, however.
PR htop-dev/htop#70 got rid of the infrastructure for generating header
files, but it left behind some code duplication.
Some of cases are things that belong in the header file and don't need
to be repeated in the C file. Other cases are things that belong in the
C file and don't need to be in the header file.
In this commit I tried to fix all of these that I could find. When given
a choice I preferred keeping things out of the header file, unless they
were being used by someone else.
`env` is allocated by checked allocation functions and can not be NULL.
This checks confuses clang analyzer and causes a null-dereference
warning on `env[size-1]`.
The MIN, MAX, CLAMP, MINIMUM, and MAXIMUM macros appear
throughout the codebase with many re-definitions. Make
a single copy of each in a common header file, and use
the BSD variants of MINIMUM/MAXIMUM due to conflicts in
the system <sys/param.h> headers.
Reasoning:
- implementation was unsound -- broke down when I added a fairly
basic macro definition expanding to a struct initializer in a *.c
file.
- made it way too easy (e.g. via otherwise totally innocuous git
commands) to end up with timestamps such that it always ran
MakeHeader.py but never used its output, leading to overbuild noise
when running what should be a null 'make'.
- but mostly: it's just an awkward way of dealing with C code.
GCC10 and Clang11 now default to -fno-common.
ld: error: duplicate symbol: jail_errmsg
>>> defined at Platform.c
>>> freebsd/Platform.o:(jail_errmsg)
>>> defined at FreeBSDProcessList.c
>>> freebsd/FreeBSDProcessList.o:(.bss+0x90)
Signed-off-by: Tobias Kortkamp <t@tobik.me>
Drop the copyright notice from the version output as a number
of people seem to be confused by what this means, and we can
do without all the (well intentioned) bug reports.
Use xStrdup instead of xMallow and strncpy
StringUtils.c: In function ‘String_split’:
StringUtils.c:86:7: error: ‘strncpy’ specified bound depends on the length of the source argument [-Werror=stringop-overflow=]
86 | strncpy(token, s, size + 1);
| ^
StringUtils.c:84:18: note: length computed here
84 | int size = strlen(s);
| ^
Enough memory is allocated.
Header.c: In function ‘Header_readMeterName’:
Header.c:157:4: error: ‘strncpy’ specified bound depends on the length of the source argument [-Werror=stringop-overflow=]
157 | strncpy(name, Meter_name(meter), nameLen);
| ^
Header.c:154:18: note: length computed here
154 | int nameLen = strlen(Meter_name(meter));
| ^
Use configure.ac to handle platform differences where some
build hosts have only a python3, or only python, binary.
Related to https://github.com/htop-dev/htop/pull/6
Promote the Arg union to a core data type in Object.c such
that it is visible everywhere (many source files need it),
and correct declarations of several functions that use it.
The Process_sendSignal function is also corrected to have
the expected return type (bool, not void) - an error being
masked by ignoring this not-quite-harmless warning. I've
also added error checking to the kill(2) call here, which
was previously overlooked / missing (?).
Extends the MakeHeader script to auto-generate correct "extern"
function declarations in some cases that it currently does not.
Related to https://github.com/hishamhm/htop/pull/981
This commit adds a "vim_mode" setting (false/`0` by default) that causes
keys to be remapped in the following way by the `ScreenManager`:
+ h -> LEFT
+ j -> DOWN
+ k -> UP
+ l -> RIGHT
+ LEFT -> h (toggle help)
+ DOWN -> j (noop)
+ UP -> k (open kill menu)
+ RIGHT -> l (lsof current process)
+ K (Shift+K) -> k (open kill menu)
+ J (Shift+J) -> K (toggle show/hide kernel threads)
+ L (Shift+L) -> l (lsof current process)
I couldn't figure out where the manpage documentation is in the repo,
though I admittedly did not look particularly hard.
I believe this change would be a welcome option for heavy vim users like myself
who would like a familiar way to get around in htop.
openzfs_sysctl_init() now returns void instead of int.
The ZfsArcStats->enabled flag is set inside the init function
now, instead of having to be set from its return value.
Preparation for more flag setting in Compressed ARC commit.
ZfsArcMeter_readStats() added and all Meter->values[] setting
moved to it, eliminating duplicated code in
{darwin,freebsd,linux,solaris}/Platform.c.
The option is only implemented on Linux. On other platforms, and on Linuxes
that do not expose the relevant sysfs file, the frequency will be 0.
The "CPU average" meter does not show a frequency, only
the individual per-CPU meters.
If no pools are imported (ARC size == 0) or the
ZFS module is not in the kernel (/proc/spl/kstat/zfs/arcstats
does not exist), then the Meter reports "Unavailable".
New meter displays same ARC stats as FreeBSD top(1).
Can be extended to other platforms that support ZFS.
Pulling kstat.zfs.misc.arcstats.c_max as the meter
total, so the meter has a meaningful value to work
up to.
The Text meter displays, first, the maximum
ARC size (Meter.total), then second, the total
ARC used, using the difference between Meter.maxItems
and Meter.curItems to "hide" the used value from the
Bar and Graph drawing functions by using an index
in Meter.values[] that is beyond curItems - 1, but
less than maxItems - 1.
A logic mistake in pull request #746 causes <sys/sysmacro.h> to be
*not* included when AC_HEADER_MAJOR (before autoconf-2.70) finds
'major' in <sys/types.h>. Though this would still build htop, it would
still bring deprecation warning in systems using glibc 2.25-2.27. Fix
the logic and suppress the warning.
Also, include config.h in Process.c for the sake of strengthening the
code.
Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
The pressure stall information (PSI) metrics provide useful information
on delays caused by waiting for CPU, IO and memory. Particularly on busy
servers it can provide a quick overview of what's "slowing things down".
This feature is supported on Linux >= 4.20.
The interface is documented here:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/accounting/psi.txt
These links provide rationale:
https://lwn.net/Articles/759781/https://facebookmicrosites.github.io/psi/
The following metrics are added, corresponding to the currently exposed
lines (see `head /proc/pressure/*`):
- PressureStallCPUSome
- PressureStallIOSome
- PressureStallIOFull
- PressureStallMemorySome
- PressureStallMemoryFull
The color scheme is the same as that used for Load Average, however I
gave it separate entries just in case someone wants to change them
specifically.
Tested on 4.20.7-arch1-1-ARCH, on the linux platform.
Also tested that other platforms still compile (changed configure to use
the unsupported platform).
Closes#879.
Disable the follow process logic in Action_pickFromVector(), when
selecting sort order or user filter, since they don't apply on specific
process.
Fix#856
In the listing of Available Meters for CPUs, the list of CPUs is always
presented by counting them from one. However, if the user prefers to
count CPUs from zero, this is sometimes confusing when fine-tuning the
meters.
Use the appropriate types when calling sysctl().
Currently, `unsigned long long int` is used for all sizes and on
FreeBSD/powerpc this causes all sysctl() calls in scanMemoryInfo()
to fail as they are actually of different sizes on powerpc, where
(sizeof(unsigned long long int), sizeof(u_long)) == (8, 4)
vs (8, 8) on amd64. This results in bogus memory sizes being
reported by htop.
Signed-off-by: Tobias Kortkamp <tobik@FreeBSD.org>
The current OpenBSD-specific CPU usage code is broken. The `cpu`
parameter of `Platform_setCPUValues` is an integer in the interval
[0, cpuCount], not [0, cpuCount-1]: Actual CPUs are numbered from
1, the “zero” CPU is a “virtual” one which represents the average
of actual CPUs (I guess it’s inherited from Linux’s `/proc/stats`).
This off-by-one error leads to random crashes.
Moreover, the displayed CPU usage is more detailed with system,
user and nice times.
I made the OpenBSD CPU code more similar to the Linux CPU code,
removing a few old bits from OpenBSD’s top(1). I think it will be
easier to understand, maintain and evolve.
I’d love some feedback from experienced OpenBSD people.
this way a remount of /proc will not reset starttimes
and we can also see startup times for processes started before the mount
of /proc
also record btime (boot time in seconds since epoch) as Linux semi-global
The source code correctly states that the maximum PID number in
the OpenBSD kernel is fixed in sys/sys/proc.h, however this was
updated in revision 1.215 (two years ago!) from 32766 to 99999.
Introduction of CP_SPIN sched state broke hard-coded state indexes
resulting in the meters incorrectly reporting bogus intr data instead of
CPU usage. Change hardcoded values to sched.h macros.
This would prevent a careless future package maintainer from creating a
release tarball with a defective configure script. :)
Also, add a warning in the autogen.sh phase if pkg.m4 is unused.
Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
With this commit:
* if pkgconfig is installed, it will expand the code inside the shell if, adding the pkgconfig-based tests for the dependencies of Linux delay accounting.
* if pkgconfig is not installed, it will add an error message inside the test of Linux delay accounting, telling the user to install pkgconfig and rebuild the configure script if they want to use Linux delay accounting.
The end result is:
* people running Linux
* will not need pkgconfig when not using delay accounting
* will need pkgconfig when using delay accounting
* if they don't have it
* they are told by configure they need to install it and re-run autogen.sh when running from Git
* they are told by configure they need to install it and re-run configure when running from the tarball
* people not running Linux
* will never need pkgconfig
...and in none of the above scenarios the generated configure script produces unexpanded macros for users checking out the sources from Git.
Header creation fails with non-utf8 locale and python3.
Simply set LC_ALL="C" and use python3 to reproduce the issue.
env LC_ALL="C" ./scripts/MakeHeader.py MetersPanel.c
Traceback (most recent call last):
File "./scripts/MakeHeader.py", line 32, in <module>
for line in file.readlines():
File "/usr/lib64/python3.5/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 956: ordinal not in range(128)
This changes is python2 and python3 compatible
cStringIO.StringIO module is removed because it is not able to accept unicode strings
https://docs.python.org/2/library/stringio.html#cStringIO.StringIO
Squashed the following commits:
* Solaris: Get LWP enumeration working
* Solaris: Make showing and hiding of kernel threads behave
* Solaris: remove usage of lwpstatus that is no longer needed
* Solaris: no discrete access to parent proc structure needed
* Solaris: Restore runtime MaxPid detection after LWP changes
* Solaris: Workaround virtual PID signal issue by shadowing kill() with a macro
* Solaris: Fix unintention double-shifting of virtual PID for LWP enumeration
* Solaris: Add LWPID to default display since LWP enumeration is also default
* Solaris: use PAGE_SIZE_KB from Process.h instead of custom definition
* Solaris: stop LWP enumeration at 1023 LWPs per proc since that is all we can handle in the virtual PID
`make htop-headers` will regenerate all '.h' headers in htop source for
all platforms.
`make clean-htop-headers` will delete all generated htop headers.
Because of the introduction of these two targets, I slightly changed
the style of platform-specific portions of makefile rules.
Please comment if you accept such a style, or need me to revert to old
style.
Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
This reduces generated Makefile.in size by 74%.
(217319 bytes -> 56326 bytes)
Automake considers that <prog>_CFLAGS and <prog>_LDFLAGS are
program-specific build rules, and when such are specified, Automake
will generate additional code just to avoid the "generic" and
package-wide AM_CFLAGS or AM_LDFLAGS. (Especially for <prog>_CFLAGS,
Automake will rename generated object files to become "prog-foo.o" and
such, and it's _a lot_ of code to achieve this in Makefile.)
There's no reason for htop to rename intermediate object files. It's
better to make things simpler.
Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
This commit adds support for Solaris, squashed from PR #741:
Summary of additions:
* Initial setup of Solaris platform directory
* Add Solaris platform into autoconf template
* Uptime and load averages
* Add dependency on libkstat
* Basic process listing
* Zone name display
* CPU detection
* Per-process memory and CPU usage parsed correctly
* Uses sysconf to discover number of CPUs, instead of more complex libkstat code
* Simple memory display working
* Reduce repetitive calls to the PAGE_SIZE macro when reading memory info
* Add Project, Contract, Task, and Pool into process properties
* Use system major()/minor() implementations and remove extraneous definition of mkdev()
* Get the STARTTIME column working properly, using the Linux implementation as a guide
The configure script relied on bash-specific extensions to shell syntax
and behavior, causing build failures on systems with other /bin/sh
implementations. This commit replaces those with equivalent constructs
that should work in all POSIX shells.
glibc 2.28 no longer defines 'major' and 'minor' in <sys/types.h> and
requires us to include <sys/sysmacros.h>. (glibc 2.25 starts
deprecating the macros in <sys/types.h>.) Now do include the latter if
found on the system.
At the moment, let's also utilize AC_HEADER_MAJOR in configure script.
However as Autoconf 2.69 has not yet updated the AC_HEADER_MAJOR macro
to reflect the glibc change [1], so add a workaround code.
Fixes#663. Supersedes pull request #729.
Reference:
[1] https://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=commit;h=e17a30e987d7ee695fb4294a82d987ec3dc9b974
Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
The "if" tests if the character at index "5" is 'r', as a first quick
check. However at index "5" will always be a colon ":". This patch fixes
the off-by-one error. htop now shows proper values in the RD_SYSC
column.
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Fixes#688, the bug regressed on 584a9bc.
On Mac OS X 10.11.6, all processes have their parents since there's a
special process named "kernel_task", whose PID and PPID are 0. As a
result, `this->processes` is never changed causing infinite `while`.
Linux commit 06eb61844d841d0032a9950ce7f8e783ee49c0d0 ("sched/debug:
Add explicit TASK_IDLE printing") exposes kthreads idling using
TASK_IDLE in procfs as "I (idle)".
Until now, when sorting the STATE ("S") column, htop used the raw
value of the state character for comparison, however that led to the
undesirable effect of TASK_IDLE ('I') tasks being sorted above tasks
that were running ('R').
Thus, explicitly recognize the idle process state, and sort it below
others.
operation is not possible to be conducted in an atomic fashion, task
scheduling effects can lead to a count greater than the number of actual
processors; this is more easily noticed on machines with several CPUs
and under heavy workload.
This patch simply adds an upper bound on cpuCount to guarantee
consistent reports of the number of running tasks at any given time.
Adds support for showing columns with linux delay accounting.
This information can be read from the netlink interface, and thus we set up a socket to read from that when initializing the LinuxProcessList (LinuxProcessList_initNetlinkSocket). After that, for each process we call LinuxProcessList_readDelayAcctData, which sends a message thru the socket after setting up a callback to get the answer from the Kernel. That callback sets the process total delay time attribute. We then set the delay percent as the percentage of time process cpu time since last scan.
GCC 7.x does some extended checks on fallthough for switch/case
statement. The warning looks like this:
warning: this statement may fall through [-Wimplicit-fallthrough=]
It can be told about implicit fallthough, however it does not
recognize comments within blocks, so move the comments outside.
The project builds a single standalone binary.
There are no libraries created - be that static or shared ones.
Thus there's no need for libtool.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
This is/was necessary only on macOS, because you needed root in order
to read the process list. This was never necessary on Linux, and
it also raises security concerns, so now it needs to be enabled
explicitly at build time.
In all the cases where sprintf was being used within htop, snprintf
could have been used. This patch replaces all uses of sprintf with
snprintf which makes sure that if a buffer is too small to hold the
resulting string, the string is simply cut short instead of causing
a buffer overflow which leads to undefined behaviour.
`sizeof(variable)` was used in these cases, as opposed to `sizeof
variable` which is my personal preference because `sizeof(variable)`
was already used in one way or another in other parts of the code.
SignalsPanel_new now fetches SIGRTMIN and SIGRTMAX and generates real-
time signals entries at runtime.
All signals between SIGRTMIN and SIGRTMAX are written in "SIGRTMIN+n"
notation, per discussion in pull request #551.
Signed-off-by: Kang-Che Sung <explorer09 @ gmail.com>
BFS-patched kernels can have kernel threads with priority -101.
This change makes priority -101 display as "RT", just like priority -100.
Related: https://github.com/hishamhm/htop/issues/314
Specifically, Platform_signals[] and Platform_numberOfSignals. Both are
not supposed to be mutable. Marking them 'const' puts them into rodata
sections in binary. And for Platform_numberOfSignals, this aids
optimization (aids only Link Time Optimization for now). :)
Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
Use strncmp() combined with a strlen() will give better performance
than a strstr in worst case. Especially when the match prefix is a
constant and not a variable.
While we are at it, replace the match() function in linux/Battery.c,
which uses a naive algorithm, with a macro that does better job by
utilizing Strings_startWith().
$ gcc --version | head -n 1
gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
$ uname -m
x86_64
$ size htop.old htop.new
text data bss dec hex filename
137929 15112 3776 156817 26491 htop.old
137784 15104 3776 156664 263f8 htop.new
Signed-off-by: Kang-Che Sung <explorer09 @ gmail.com>
Commit "Make PgDown behavior more usual." 759caf0f8fa593430adea676fc64612b5197dca8
silently changes the PageDown scrolling behavior that, instead of
scrolling one window down until the end of the window touches the end
of the list, the window simply repositions itself in a way that the
selected item always become the last item in the new window.
The commit reverts the behavior, and also fixes sanity conditionals
so that the scrollV variable will _never_ become negative or out-of-
bound.
Fixes issue #532. Also keep the problem #480 addressed.
Signed-off-by: Kang-Che Sung <explorer09 @ gmail.com>
Before:
SpaceStyle EnterMove DelDeleteEscDone |
~~~~~ ~~~~~ ~~~ ~~~ |
UpUp DnDown LtLeft RtRight EnterConfirmDelDeleteEscDone |
~~ ~~ ~~ ~~ ~~~~~ ~~~ ~~~ |
After:
SpaceStyle EnterMove DelDeleteF10Done
~~~~~ ~~~~~ ~~ ~~~ ~~~
SpaceStyle EnterLock UpUp DnDown <-Left ->Right DelDeleteF10Done
~~~~~ ~~~~~ ~~ ~~ ~~ ~~ ~~ ~~~ ~~~
* Align 'Delete' and 'Done' to the right to match functions on other
screens. (Accidental clicking is avoided as a side benefit.)
* You could change meter type while in moving mode. New bar now hints
this.
* Two Enter key functions are put in the same place and so mouse clicks
there act like functions toggle. (The wording change to 'Lock' is
also to reflect this.)
* '<-' and '->' instead of 'Lt' and 'Rt' abbreviation as the latter is
not widely seen and arrows shapes are obvious. :)
* 'Esc' key for 'Done' in this context may not be intuitive, comparing
to 'F10'. While I wish there be a Cancel/Undo function for 'Esc', it
wouldn't hurt if we write 'F10' for 'Done' on functions bar for now.
This will be used when cross-compiling with ncurses*-config generated for the
target, using constructs like
HTOP_NCURSES_CONFIG_SCRIPT=/path/to/ncurses5-config
Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com>
* Dynamically adjust the size of line reads.
* Remove some more uses of fgets with arbitrary sizes.
* Fix reading of lines and width of n column.
Fixes#514.
Rewrite the scrolling part in the man page so that each key become clearer on
what it does. Also officially document the Alt+{h,j,k,l} key alternatives and
Ctrl+A, Ctrl+E, '^', '$' keys (see issue #508).
__attribute__((nonnull)) will help catching "calling with NULL" mistake on
compile time.
I also convert xStrdup into a macro, that will do assert() inline when the
code is *not* built with -DNDEBUG . For release builds (with -DNDEBUG),
preprocessor trick will ensure that generated code remains the same.
This effectively reverts "Stricter strdup." 4674b4a7320bb6b003a4e3b3840027573691e60d
If str is NULL upon the calling of strdup(), it should crash with SIGSEGV.
Just let it crash. Adding the "if (!str) fail();" code serves nothing but
bloat.
3 effects in this commit, with the first being the main one:
1. Fix the "`missing' script is too old or missing" warning. See:
<https://lists.gnu.org/archive/html/automake/2010-08/msg00108.html>
2. By moving AC_CANONICAL_TARGET down in order, we are now able to
set the directory for auxiliary scripts. For now it's still './'.
I added the line "AC_CONFIG_AUX_DIR([.])" to show that the directory
change is possible.
3. AC_USE_SYSTEM_EXTENSIONS includes checks from AC_PROG_CC, by moving
the former macro down, we can save size in 'configure' by not
generating repeated checks.
AC_HELP_STRING -> AS_HELP_STRING
AC_TRY_COMPILE -> AC_COMPILE_IFELSE([AC_LANG_PROGRAM([...])],...)
AC_CONFIG_HEADER -> AC_CONFIG_HEADERS
AC_PROG_LIBTOOL -> LT_INIT
Note: There might be more deprecated macros that I haven't noticed.
I just wish to avoid painful highlighting from my text editor (gedit)
that complains about them. :)
The (this_) token was not expanded properly, but the bug was not caught
because all uses of this macro specifies (this_)=this .
Also parenthesize macro tokens to prevent further problems.
Rationale (copied from htop issue #471):
The function name "setValues" is misleading. For most OOP (object-
oriented programming) contexts, setXXX functions mean they will change
some member variables of an object into something specified in
function arguments. But in the *Meter_setValues() case, the new values
are not from the arguments, but from a hard-coded source. The caller
is not supposed to change the values[] to anything it likes, but
rather to "update" the values from the source. Hence, updateValues is
a better name for this family of functions.
Removed a loop that sets the bar[] buffer with spaces and merged that
task to the snprintf() call just below. No need for the barOffset
variable. Display behavior is unchanged.
Size comparision (when compiled on Ubuntu 14.04 64-bit):
$ size htop.old htop.new
text data bss dec hex filename
137312 15112 3776 156200 26228 htop.old
137216 15112 3776 156104 261c8 htop.new
Just assume Platform_meterTypes[0] is always &CPUMeter_class for every
platform. This removes a conditional in AvailableMetersPanel_new().
Also adds some comments about the logic here. Without assuming
Platform_meterTypes[0], the (int i=1) clause in this for loop will not
make sense. (I.e. Why not (int i=0)? )
Also replaced a sprintf() call with safer snprintf() in code further
below.
Two changes in this commit:
- All meters now explicitly specify "maxItems" property, even for just
1 item. (Exception is "container" CPU meter classes, which use
CUSTOM_METERMODE.)
- "maxItems" being 0 is now allowed. This will let bar meters and graph
meters render an empty meter.
calloc() allows 'nmemb' or 'size' to be zero, in which case NULL may be
returned. Letting htop die because of either argument being zero doesn't
make sense.
As a side note: As size_t is unsigned, compiler should be able to optimize
conditional (nmemb > 0 && size > 0) to (nmemb && size). This theorically
shouldn't increase code size too much.
Namely:
o use malloc where an xCalloc slipped in
o safeguard against an empty arg list - I don't think it's possible,
but it would be potentially exploitable
o we need to initialize the arg string to an empty string because we no
longer use strlcpy(3)
o annotate a tricky use of strlcpy(3)'s truncation
Including:
o set *basenameEnd even in error cases (FreeBSD probably needs this)
o use kvm_openfiles(3) rather than kvm_open(3) so that we can report
errors (as with FreeBSD)
o sanify the process argument list creation by using strlcat(3)
o drop the pageSizeKb variable and use the PAGE_SIZE_KB macro directly,
as the page size can't change anyway
o clean up a few macros, add MINIMUM() and MAXIMUM() (should be
mirrored to FreeBSD)
o fix some syntax
o add some useful comments
This involves switching from kvm_open(3) to kvm_openfiles(3). The only
difference is that the latter has saner error reporting (see the man
page for details). We can now fatally report the error rather than just
calling assert(3).
Once a process goes zombie on Linux, /proc/PID/cmdline
gets empty. So, when we detect it is a zombie we stop
reading this file.
For processes that were zombies before htop started,
there's no way to get the full name.
Closes#49.
This simplifies the protocol between the platform-independent
and platform-specific parts. The platform-specific parts
were supposed to re-determine the value of process->show
on each iteration, and the Darwin subsystem wasn't doing that.
Instead of adding the code to the Darwin part, I lifted the
burden of the OS-specific of resetting process->show: now
they can choose to hide a process if they want to (e.g.
detecting kernel threads) but are not required to
(e.g. on Darwin where we're not listing threads separately (yet?)).
Fixes tree view collapsing/expanding on OSX. Closes#416.
Got a report in #397 that htop runs in NetBSD
masquerading as Linux and using a compatibility /proc
(like we used to in FreeBSD) and that it builds fine
apart from this syscall.
htop currently expects m_size and m_resident in pages (Process.c).
According to the proc_info.h header, the values returned by libproc
are in bytes:
http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/sys/proc_info.h
Eventually we should change the htop crossplatform API to expect memory
in bytes, but this is the smaller change that should fix it.
Closes#385.
(Cherry-picked from d56bcd8e0d8d6a177fc2e40db32fc73ea4588684, the
experimental graph coloring branch)
The variable 'dot' in GraphMeterMode_draw now means "maximum number of
dots per value (column) in graph". The old meaning was "amount of value
that is to be represented by a dot" and was always a fraction. Due to
a limitation in floating point computing, if GRAPH_HEIGHT were not a
power of 2, then rounding errors will occur on numbers like (1.0/3).
(Currently GRAPH_HEIGHT is 4 and so no precision loss.) 'dot' was used
as a divisor, and it's "division by a reciprocal". We change that to
simple multiplication.
(Cherry-picked from e93028d7fa0c5f00b5dc3336fd28abaf905cd572, the
experimental graph coloring branch)
Currently GRAPH_HEIGHT=4 . This prevents hard-coding the height of the graph
meters, and allows user to change it at compile-time.
With the CLAMP macro replacing the combination of MIN and MAX, we will
have at least two advantages:
1. It's more obvious semantically.
2. There are no more mixes of confusing uses like MIN(MAX(a,b),c) and
MAX(MIN(a,b),c) and MIN(a,MAX(b,c)) appearing everywhere. We unify
the 'clamping' with a single macro.
Note that the behavior of this CLAMP macro is different from
the combination `MAX(low,MIN(x,high))`.
* This CLAMP macro expands to two comparisons instead of three from
MAX and MIN combination. In theory, this makes the code slightly
smaller, in case that (low) or (high) or both are computed at
runtime, so that compilers cannot optimize them. (The third
comparison will matter if (low)>(high); see below.)
* CLAMP has a side effect, that if (low)>(high) it will produce weird
results. Unlike MIN & MAX which will force either (low) or (high) to
win. No assertion of ((low)<=(high)) is done in this macro, for now.
This CLAMP macro is implemented like described in glib
<http://developer.gnome.org/glib/stable/glib-Standard-Macros.html>
and does not handle weird uses like CLAMP(a++, low++, high--) .
This is what OpenBSD's top(1) does when the libkvm call fails, and it's
a good idea.
This commit also fixes process name construction. The space was being
written one character too far.
I forgot how awful the process name logic was. It was an initial hack to
get it running, and I forgot to clean it up.
I also had to change a few includes and error function uses.
this caused htop to show processes as if freebsd kernel was their parent.
on next pass reparenting code took chance to run, and that caused process to jump around.
this fixed behaviour should be the correct one
KEY_RESIZE wasn't handled by the incremental search. Resulting in this
bug:
* Set your terminal window to a small size.
* Press '\' to filter the processes
* Maximize your terminal window
* The list of processes didn't resize.
This change fixes this bug.
Thank you Julian Andrews (@julianandrews) for finding this bug.
on Darwin, htop needs to run with root privileges to display information
about other users processes. This commit makes running htop SUID root a
bit more safe.
reclaimable slab as cached memory.
Hopefully this presents a more truthful representation of
available vs. used memory on Linux.
See brndnmtthws/conky#82, #242, #67, #263.
PID1 or even any other PID (if there are custom reapers in the system).
Similar issue with jails, elevated process can ask kernel to attach itself into any jail at any time,
thus JID and jail name can change each refresh cycle.
Implementations for Linux (tested) and FreeBSD (still untested, thanks to @etosan for providing the table).
Darwin and OpenBSD(ping @mmcco) builds should be broken now, pending their own tables.
Seems FreeBSD kernel can spawn both kernel processes (what is what htop currently sees) and kernel threads.
For now let's consider kernel processes kernel "threads".
* size_t nmemb (number of elements) first, then size_t size
* do not assume char is size 1 but use sizeof()
* allocate for char, not pointer to char (found by Michael McConville,
fixes#261)
* Use MIN() and MAX() to make sure values are inside bounds. This should
fix an issue where Meters were missing dots at the bottom.
* Remove variable 'level' and calculate on the fly.
With more dimensional arrays we have to define the array size. Use
one dimensional arrays to be more flexible.
Additionally this allows to shrink array size for ASCII.
Add a setting to hide all but the last component from the programme
path, leaving only the "basename". Makes htop more usable on smaller
screens, or systems with longer than average paths. Off by default.
"Highlight program basename" will still be respected, to further
visually separate process names from their arguments.
htop uses scanf functions to parse values from proc filesystem. This
breaks when initializing locale for LC_NUMERIC because of unexpected
commas. So initialize locale for LC_CTYPE only.
This has two effects:
* The locale may have impact on string formatting. So depending on the
locale we may end up with different decimal point.
* We can use nl_langinfo() for UTF-8 detection.
gcc gives warnings like this:
warning: ignoring return value of ‘fscanf’, declared with attribute
warn_unused_result
Assign value to a variable, cast to (void) to discard it.
It is now accessible via F6 when on tree view (as a bonus, it is
now also reachable via the mouse). The function bar now dynamically
changes to reflect the toggle nature of the tree-view mode (F5)
and the F6 key serves as expand/collapse when on tree mode,
and its previous behavior of bringing up the "Sort By" menu
(which only made sense on non-tree mode). Users wishing to go to
the "Sort By" menu straight from Tree View can still do so with the
"<" and ">" keys (the top-compatible keys for sort selection).
I could not reproduce the crash in current SVN
(I've been adding checks for problems like this),
but the sanity check looks correct.
Thanks to Cybjit. Closes#3481053.
* Performance improvements
* Support for splitting CPU meters into two or four columns
(thanks to Wim Heirman)
* Switch from PLPA, which is now deprecated, to HWLOC.
* Bring back support for native Linux sched_setaffinity,
so we don't have to use HWLOC where we don't need to.
* Support for typing in user names and column fields in selection panels.
Fix subtree hiding
Fix reading of CPU values in hidden threads
Fix hiding of zombie processes as kernel threads
Remove "debug proc" code
Code cleanup in processElements
* BUGFIX: Correct page size calculation for FreeBSD systems
(thanks to Andrew Paulsen)
* Allow compilation without PLPA on systems that don't support it
(thanks to Timothy Redaelli)
When user threads are hidden, process now shows the
sum of processor usage for all processors. When user
threads are displayed, each thread shows its own
processor usage, including the root thread.
(thanks to Bert Wesarg for the report)
Also, add option to display thread colors differently.
disable useless code in release builds such as runtime type-checking on
dynamic data structures and process fields that are not being computed,
faster(?) method for verifying the process owner (still need to ensure
correctness), don't destroy and create process objects for hidden kernel
threads over and over. Phew. I shouldn't be doing all this today, but I
could not resist.
Panel_add(super,(Object*)CheckItem_newByRef("Merge exe, comm and cmdline in Command",&(settings->showMergedCommand)));
Panel_add(super,(Object*)CheckItem_newByRef("- Try to find comm in cmdline (when Command is merged)",&(settings->findCommInCmdline)));
Panel_add(super,(Object*)CheckItem_newByRef("- Try to strip exe from cmdline (when Command is merged)",&(settings->stripExeFromCmdline)));
Panel_add(super,(Object*)CheckItem_newByRef("Highlight large numbers in memory counters",&(settings->highlightMegabytes)));
Panel_add(super,(Object*)CheckItem_newByRef("Leave a margin around header",&(settings->headerMargin)));
Panel_add(super,(Object*)CheckItem_newByRef("Detailed CPU time (System/IO-Wait/Hard-IRQ/Soft-IRQ/Steal/Guest)",&(settings->detailedCPUTime)));
Panel_add(super,(Object*)CheckItem_newByRef("Count CPUs from 1 instead of 0",&(settings->countCPUsFromOne)));
Panel_add(super,(Object*)CheckItem_newByRef("Update process names on every refresh",&(settings->updateProcessNames)));
Panel_add(super,(Object*)CheckItem_newByRef("Add guest time in CPU meter percentage",&(settings->accountGuestInCPUMeter)));
Panel_add(super,(Object*)CheckItem_newByRef("Also show CPU percentage numerically",&(settings->showCPUUsage)));
Panel_add(super,(Object*)CheckItem_newByRef("Also show CPU frequency",&(settings->showCPUFrequency)));
#ifdef BUILD_WITH_CPU_TEMP
Panel_add(super,(Object*)CheckItem_newByRef(
#if defined(HTOP_LINUX)
"Also show CPU temperature (requires libsensors)",
#elif defined(HTOP_FREEBSD)
"Also show CPU temperature",
#else
#error Unknown temperature implementation!
#endif
&(settings->showCPUTemperature)));
Panel_add(super,(Object*)CheckItem_newByRef("- Show temperature in degree Fahrenheit instead of Celsius",&(settings->degreeFahrenheit)));
#endif
#ifdef HAVE_GETMOUSE
Panel_add(super,(Object*)CheckItem_newByRef("Enable the mouse",&(settings->enableMouse)));
#endif
Panel_add(super,(Object*)NumberItem_newByRef("Update interval (in seconds)",&(settings->delay),-1,1,255));
Panel_add(super,(Object*)CheckItem_newByRef("Highlight new and old processes",&(settings->highlightChanges)));
Panel_add(super,(Object*)NumberItem_newByRef("- Highlight time (in seconds)",&(settings->highlightDelaySecs),0,1,24*60*60));
Panel_add(super,(Object*)NumberItem_newByRef("Hide main function bar (0 - off, 1 - on ESC until next input, 2 - permanently)",&(settings->hideFunctionBar),0,0,2));
#ifdef HAVE_LIBHWLOC
Panel_add(super,(Object*)CheckItem_newByRef("Show topology when selecting affinity by default",&(settings->topologyAffinity)));
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.