Live data from Hacker News

Why bother with argv[0]?

wietzebeukema.nl

161–170 of 277 posts

Re: Why bother with argv[0]?

#161

Earlier quoted context omitted.

Also if you want a program to call itself, which is sometimes useful, this way lets you actually call the same program, rather than assuming the name and path.

There's no guarantee that the name and the path are still the same executable that is running, or that they even exist anymore.

Unless you are on Windows

Re: Why bother with argv[0]?

#162

Earlier quoted context omitted.

What about compiled binaries that for one reason or another is doing an execve() on "/usr/bin/cmp" or some such thing? Do you propose changing every script and every binary on earth that expects Busybox to be a POSIXy, Unixy environment?

No you make this script: #!/bin/sh exec /bin/busybox cmp And place it at /usr/bin/cmp

So now to execute a program that could have been a direct run you have to fire up a shell, have it parse the file, and execute the instruction? Not really a great thing...

Plus, you have to know the absolute path of the executable busybox, not something you always know in advance.

Re: Why bother with argv[0]?

#164

Earlier quoted context omitted.

Not an author, but there's a good alternative. If busybox was edited to ignore argv[2], then applets could be called via shebangs, instead of symlinks: $ echo '#!/path/to/busybox echo' > myecho $ chmod +x myecho $ ./myecho 123 ./myecho 123 Right now this doesn't work properly, because "./myecho" (argv[0]) gets placed into argv[2] of the process. Otherwise, this technique IMHO is better than symlinks: - Each applet us…

Well that would be inefficient. For each command you run the kernel has to read the file, detect that it has a shebang, parse the shebang line, and then finally load the actual executable in memory. That could be a performance problem, since busybox is used typically in embedded systems that doesn't have a lot of resources: imagine a shell script that runs a command in a loop, it has to do a lot of extra work. Finall…

I’m going to challenge you on the performance angle. Instead of doing the shebang line, it has to traverse the filesystem to resolve the link. I suspect that’s probably more expensive than parsing the shebang line. Indeed, a shell script that runs a command in a loop should have busybox detecting the built in command & executing it inline without spawning executables via the file system (this is common in bash as well btw).

There are valid reasons but I think the performance angle is the weakest argument to make.

Re: Why bother with argv[0]?

#165
post #65
post #51

Earlier quoted context omitted.

I would not say it in such absolute way - /proc/self/exe has downsides as well. As this resolves all symlinks, so this breaks all the things that depend on argv[0], like nice help messages, python's virtualenv, name-based dispatch, and seeing if the program which was executed via symlink or not. A lot of times you know you never called chdir(), in which case I'd actually recommend executing argv[0], as this is nicest…

Those are all cases where you're using argv[0] as an argument to the program where it's appropriate. Using it as the path to spawn a child process is incorrect . You're free to re-use it as an argument. I have fixed enough software that made this mistake that I'm confident to be absolute about it. It's a very easy mistake to make but it's really annoying when software makes it and someone needs to deal with it at a h…

What’s the issue with using argv[0] as a way to spawn yourself? I don’t recall running into a lot of issues.

Re: Why bother with argv[0]?

#166
post #116

So obviously claiming that there's no good reason for process to read argv[0] is either demonstrating the author's ignorance or needs a much stronger defense; I'd be fascinated to hear how they think busybox should work on an OpenWrt box with a 16MB root filesystem. However , I am willing to consider the discussion about whether there could be merit to restricting the ability to write that value; I could imagine a sy…

Isn't the reason for busybox multi-call binary mostly just ELF being bloated? So the answer for resource constrained systems would be to have more efficient executable format. I don't see why multi-call binary + bunch of symlinks would be intrisically much more size-efficient than something purpose-built.

a lot of code is shared between different tools. Busybox has one copy of those. Before you mention shared libraries. There is still overhead, as well as complicating the usage (it needs to find a shared lib when starting instead of just having all it needs in the binary). This isn't really a property of the executable format. Any format would have the same problem.

Re: Why bother with argv[0]?

#167
post #102

Earlier quoted context omitted.

That seems unnecessarily harsh. I don't think that's the gist of the article, but the throwaway suggestion of 'just make lots of copies, who cares about diskspace' is insufficient and thus distracts. It's.. a single line about solutions in an article that isn't _about_ solving problems, it's about highlighting a problem exists and that it's worth solving. I read the article more as: There is __often__ no good reason…

> Show the actual file path, and always an absolute one - that way you avoid confusion about which executable you're actually running, and it's just as readable if not more readable for every app _except_ those who care about argv[0], e.g. if you ran `/bin/dd` and it's actually busybox, in taskman you'd see `/bin/busybox` instead which'd be worse than seeing 'dd'. This was kind of in the middle of your complaint abou…

> On a unix filesystem, a file that's hard linked with multiple names has no single 'actual name'

The same is true for hard linked files on Windows. That never stops Windows from showing you a path.

There is almost always an "obviously right" path (the one used when opening the file). And if you lost track of that, deterministically choosing one of the possible paths is almost always more user friendly than just chowing inode numbers.

Re: Why bother with argv[0]?

#168

Earlier quoted context omitted.

These days, Windows Calculator takes up more memory than mIRC. Tell me why a simple calculator app needs more memory than a complete multi-server implementation of the IRC protocol (including SSL/TLS), not to mention a full scripting engine.

>These days, Windows Calculator takes up more memory than mIRC. I'd be somewhat surprised if that's actually true, but I haven't used mirc for years (started using hexchat once I was honest about the fact that I wasn't going to pay for mirc) but I think a lot of that is an inherent part of windows development now, basic c# projects with graphics end up being pretty big. Interestingly enough, the new windows calculato…

> I'd be somewhat surprised if that's actually true

It 100% is.

I launched Calculator and according to the Processes tab in Task Manager, "Calculator" is using 31.2 MB of memory, and mIRC is taking 17.2 MB. That's with Calculator being freshly launched and no input given, compared to mIRC being connected to 1 server and in 8 channels.

If I go to the Details tab, then the story it tells is even worse. I include several metrics here:

Working Set: - Calculator: 91 MB - mIRC: 40 MB

Memory (private working set): - Calculator: 30 MB - mIRC: 18 MB

Memory (shared working set): - Calculator: 61 MB - mIRC: 23 MB

Commit size: - Calculator: 67 MB - mIRC: 49 MB

By basically every metric, mIRC uses less memory than Calculator.

> it's not a 'simple calculator app', it's a full featured graphing calculator even if most people don't use those features.

The only feature that should significantly impact the memory usage is the graphing. All its little measurement conversion options shouldn't take more than a few kilobytes. But even with the graphing, it's absurd that it takes more memory than the total memory I would have had in a 486 machine that could easily have run an app with the same features.

> but I think a lot of that is an inherent part of windows development now, basic c# projects with graphics end up being pretty big.

I suppose the price you pay for almost guaranteed memory safety and ease of development through abstractions means your base executable memory footprint includes an entire language runtime.

Re: Why bother with argv[0]?

#169

Earlier quoted context omitted.

i may have missed it, but where does the C Standard say anything about access to a symbol table? or even if such a thing exists. and as for IBM i managed to use all sorts of OSs in VMs on IBM hardware back in the 1980s. Which did you have problems with?

The parser in C has to keep track of the symbol table to handle cases like typdef int myint; myint x; which is unusual among programming languages. Sure I used VM on IBM hardware in the 1980s and it was great. I also used timesharing systems on the PDP-8 (what atrocious hardware!), the PDP-11 and the PDP-10/20 in the 1970s. Although the 360 was superior in so many respects (except for the slow interrupt handling) it…

well, that's like saying the compiler when it sees something like:

   int x;
   x = 1;
it has to keep track of "x". of course it does. what programming languages don't?

Re: Why bother with argv[0]?

#170

Earlier quoted context omitted.

Not an author, but there's a good alternative. If busybox was edited to ignore argv[2], then applets could be called via shebangs, instead of symlinks: $ echo '#!/path/to/busybox echo' > myecho $ chmod +x myecho $ ./myecho 123 ./myecho 123 Right now this doesn't work properly, because "./myecho" (argv[0]) gets placed into argv[2] of the process. Otherwise, this technique IMHO is better than symlinks: - Each applet us…

Well that would be inefficient. For each command you run the kernel has to read the file, detect that it has a shebang, parse the shebang line, and then finally load the actual executable in memory. That could be a performance problem, since busybox is used typically in embedded systems that doesn't have a lot of resources: imagine a shell script that runs a command in a loop, it has to do a lot of extra work. Finall…

> Well that would be inefficient. For each command you run the kernel has to read the file, detect that it has a shebang, parse the shebang line, and then finally load the actual executable in memory.

Those that exist today would, but no kernel would have to work like that.

Once you've agreed that monolithic kernels have merits, you've accepted that the kernel can do whatever it wants to make this efficient—including being complicit in this scheme and leapfrogging over most of what you just described.

Post reply on HN