Skip to content

Allocate COMMAND (cmdline) and comm buffers dynamically#1865

Open
fasterit wants to merge 1 commit intohtop-dev:mainfrom
fasterit:dynamic-buffer-for-cmdline
Open

Allocate COMMAND (cmdline) and comm buffers dynamically#1865
fasterit wants to merge 1 commit intohtop-dev:mainfrom
fasterit:dynamic-buffer-for-cmdline

Conversation

@fasterit
Copy link
Member

Fixes #1860

This PR was developed by DLange/Faster IT with Microsoft Copilot

Fixes htop-dev#1860

This PR was developed by DLange/Faster IT with Microsoft Copilot
@fasterit
Copy link
Member Author

I left the initial buffer at 4096 +1 bytes so we can compare performance. I suggest we ramp up from 512 bytes if/when we commit this to main as we can save memory this way and it comes rather "for free" with the dynamic allocation.

@Explorer09
Copy link
Contributor

@fasterit This thing is very similar to the dynamic buffer code I've done in #1821.

My code snippet (generic/Demangle.c):

char* Generic_Demangle(const char* mangled) {
   // The cplus_demangle() API from libdemangle is flawed. It does not
   // provide us the required size of the buffer to store the demangled
   // name, and it leaves the buffer content undefined if the specified
   // buffer size is not big enough.
   static size_t bufSize = 128;
   static char* buf;

   while (true) {
      if (!buf) {
         buf = malloc(bufSize);
         if (!buf)
            return NULL;
      }

      int res = cplus_demangle(mangled, buf, bufSize);
      if (res == 0)
         break;
      if (res != DEMANGLE_ESPACE || bufSize > SIZE_MAX / 2)
         return NULL;

      bufSize *= 2;
      free(buf);
      buf = NULL;
   }

   return strdup(buf);
}

Notice that I keep the buffer and not deallocate it after use. I think this can save some time when there are lots of strings needed to fetch (and all of them need a dynamically-sized temporary buffer). I don't know if it is a good idea.

@BenBE BenBE added enhancement Extension or improvement to existing feature Linux 🐧 Linux related issues labels Jan 18, 2026
#endif

/* Maximum buffer size for reading COMMAND / comm */
#define MAX_CMDLINE_BUFFER_SIZE (2 * 1024 * 1024 + 1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the 4K+1 is multiplied a bunch of times, by the time we reach this size, it's more like 2M+512.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, see my comment on suggesting to start with 512 bytes in production

@Explorer09
Copy link
Contributor

I have a question: How does this solve the original bug (#1860) when the new proposed solution still has a length limit?

@fasterit
Copy link
Member Author

@Explorer09 Because the length limit is 2 MB now, not 4096 Bytes. As much as I know currently, 2MB seems to be the practical limit of cmdlines in the Linux kernel these days. At least xargs thinks so, see this comment in the linked issue.

@Explorer09
Copy link
Contributor

@Explorer09 Because the length limit is 2 MB now, not 4096 Bytes. As much as I know currently, 2MB seems to be the practical limit of cmdlines in the Linux kernel these days. At least xargs thinks so, see this comment in the linked issue.

I am uncomfortable when the whole 2 MB long command line is kept in htop's memory. If we keep that line in memory only to let the filter function work, I think an alternative approach is to read and "grep" from the file in procfs on demand.

@BenBE
Copy link
Member

BenBE commented Jan 19, 2026

@Explorer09 Because the length limit is 2 MB now, not 4096 Bytes. As much as I know currently, 2MB seems to be the practical limit of cmdlines in the Linux kernel these days. At least xargs thinks so, see this comment in the linked issue.

I am uncomfortable when the whole 2 MB long command line is kept in htop's memory. If we keep that line in memory only to let the filter function work, I think an alternative approach is to read and "grep" from the file in procfs on demand.

Having 2MiB in memory is much better from a performance PoV than having to grep 2000+ files just in case one of the processes matches something. It's a trade-of between memory vs. repeatedly doing several syscalls just to safe a few kB of memory. You can still do "keep the buffer for next read and strdup for internal storage".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Extension or improvement to existing feature Linux 🐧 Linux related issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

F4 filtering does not find all results

3 participants