HNHacker News
TopNewBestAskShowJobs

btrask

1,914 karma · joined January 20, 2011

https://bentrask.com - https://github.com/btrask
submissionscomments
btrask··on .NET 6 vs .NET 5 speedup
I might be the last person to realize this, but did Microsoft name it .NET because they already had COM?
btrask··on Willingness to look stupid
This article does not undermine its own point. In fact, very, very few articles ever undermine their own point. In order to undermine your own point it means you've failed to construct a logical chain of thought. But that is what people do all the time in their daily lives. Maybe children would undermine their own points, or someone posting their first ill-thought comment on Facebook. But I think most people will learn how to construct an argument by their second time publishing one.

In this case, the article is not about 'the joys of being too dumb to breathe'. It's about how 1. looking stupid is not the same as being stupid, and 2. looking stupid can be beneficial in the long run. The author does not need to actually be stupid once in order to support this idea.

And I have to worry if you think he's "bragging" about merely looking stupid, as if that weren't bad enough. Maybe if you identify as stupid I could understand the offense.

To the author, Dan Luu: I like your article and I think you're on the right track!

btrask··on Curl is C (2017)
I didn't like Regehr's proposal because I don't want a friendly dialect of C. I mostly just want C the way it worked up until, say, GCC 4.x.

I don't know specifically how to fix the standard, although I've been thinking about it. A simple idea would be like the Linux mandate "don't break userspace." The language-lawyering has to stop, and more rules are unlikely to help.

btrask··on Curl is C (2017)
Or... the standard just has bugs which could be fixed. Bugs meaning: being out of line with the history of C and large amounts of C code in the wild.

The more people beat the standard drum, the worse things will get until the standard itself is fixed.

Other languages that don't have a standard don't have this problem (but they do have other problems).

btrask··on Defensive Programming
Yeah, in C you need to use assertions (or simple checks) for things that might be null.

That said the compiler isn't infinitely smart (thank god) and complex null derefs will "safely" make it to runtime. (What a sad world we're in.)

btrask··on Defensive Programming
If you are transferring ownership, you would do

    p2 = p1; p1 = NULL;
However if you are intentionally doing multiple ownership, then yes you can still have problems.
btrask··on Tokio 1.0 – async runtime for Rust
Green threads.
btrask··on Tokio 1.0 – async runtime for Rust
I see now, I misunderstood your original post. You were saying async/await is necessary because futures work badly, not because all the alternatives (i.e. locks) work badly.

Sorry, my mistake!

Edit to add: futures work badly in every language, so there's no shame in the borrow checker not working with them.

Edit 2: But in that case we're back to "why would Rust want async/await over (potentially green) threads with its first-class support for locks?"

btrask··on Tokio 1.0 – async runtime for Rust
Whether it's kernel threads or green threads, the same patterns (locks, etc) are possible. Locks are supposed to be the borrow checker's bread and butter, because it can guarantee they are held before accessing shared state. But now you're saying "the borrow checker makes writing code without [async/await] difficult, inefficient, and unergonomic."

I'm not saying locks are better than async/await (although they are[1]). You're saying the borrow checker itself can't handle them in real world use?

[1] https://journal.stuffwithstuff.com/2015/02/01/what-color-is-...

btrask··on Tokio 1.0 – async runtime for Rust
Wait, what? What happened to "fearless concurrency"? I thought this was supposed to be one of the borrow checker's selling points!

https://blog.rust-lang.org/2015/04/10/Fearless-Concurrency.h...

btrask··on Ask HN: About Financial Inequity
So over the last thousand years salt has been a hyper-inflationary asset, and you're trying to tell me I'm rich for owning some?
btrask··on Software Needs Philosophers (2006)
This article is such a great opportunity for introspection ("what do we need in order to do better?"). It's too bad that the top comment has turned it into an opportunity for egotism ("they need us!").
btrask··on What is your favorite C programming trick? (2009)
Very reasonable! Thank you for the discussion :)
btrask··on What is your favorite C programming trick? (2009)
Taking a pointer-to-pointer is intentional to make it clear that the pointer will be modified. That's actually the most important difference from nn3's version IMHO.
btrask··on What is your favorite C programming trick? (2009)
Good points, thank you for explaining!

I can see an argument for wrapping it in a macro so you can turn off nulling in debug builds (ASan might even have hooks so you can automate this, I know Valgrind does). But use-after-free is worse than just double-frees, and if you read a dangling pointer in production there's no real way to catch it AFAIK. Last I heard (admittedly been a few years since I checked), you're not supposed to deploy ASan builds because they actually increase the attack surface.

So, your program's memory is full of these dangling pointers, and at some point you will have a bug you didn't catch and use one. And you can't even write an assertion to check that it's valid. What do you propose?

And again to clarify, I'm not trying to advocate for hiding bugs. I want to catch them early (e.g. with assertions), but I also want to avoid reading garbage at runtime at all costs, because that's how programs get pwn'd.

btrask··on What is your favorite C programming trick? (2009)
I tried making it a plain function at one point but ran into some weirdness around using void * * with certain arguments (const buffers?). You don't want to accept plain void * because it's too easy to pass a pointer instead of a pointer to a pointer. Using a macro is (ironically) more type safe.

Maybe someone else could figure out how to do it properly, since I'd definitely prefer a function.

btrask··on What is your favorite C programming trick? (2009)
do {} while(0) is a common idiom for macros in C, because it consumes the trailing semicolon, which a bare {} block doesn't do.

    if(x) MACRO();
    else something();
expands to

    if(x) { ... }; // Error!
    else something();
btrask··on What is your favorite C programming trick? (2009)
I appreciate you defending me, but I don't think he was trying to be dishonest.
btrask··on What is your favorite C programming trick? (2009)
I don't think that's fair in this case because nulling out pointers isn't the first line of defense. If you forget to do it once, it's not going to cause a bug in and of itself. You can easily grep the code periodically to find any cases you missed.
btrask··on What is your favorite C programming trick? (2009)
Help me out here, because I'm really trying to understand. Are you saying that dangling pointers that blow up if you double-free them is an "automatic check"? If not, what kind of automatic check are you talking about?

If the extra code is really that bothersome, just use a macro or wrapper function.

btrask··on What is your favorite C programming trick? (2009)
In C you can use [0] for postfix pointer dereferencing.
btrask··on What is your favorite C programming trick? (2009)
Here's the actual macro I (sometimes) use:

    #define FREE(ptrptr) do { \
        __typeof__(ptrptr) const __x = (ptrptr); \
        free(*__x); *__x = NULL; \
    } while(0)
There might be a better way of doing it though. Also, __typeof__() obviously isn't standard C.

Edit to add: I've honestly been moving away from using a macro and just putting both statements on one line like in the OP. For something so simple, using a macro seems like overkill.

btrask··on What is your favorite C programming trick? (2009)
Every problem can be solved in many different ways. If you think you've already got use-after-free bugs under control, then more power to you! You absolutely have to concentrate your effort on whatever your biggest problems are.

But I'll also say that if you don't have any use-after-free bugs in the history of a large C codebase... you might not even be on the lookout for them? I still have them sometimes, mainly when it comes to multiple ownership. And those are just the ones I found eventually.

So yes, different strokes for different folks, but if you make the effort to incorporate tricks like this into your "unconscious" coding style, the ongoing effort is pretty minimal. Even if you decide this trick isn't worth it, there are countless others that you might find worthwhile. I'm always on the lookout for better ways of doing things.

btrask··on What is your favorite C programming trick? (2009)
All code is full of vulnerabilites. If you say your code isn't, then I'm sure it is. I just do the best I can to keep the error rate as low as possible. But it's a rate, and it's never zero.

Also, it's not just about vulns in security-critical code. It's also about ordinary bugs. Why not be a little more careful? It won't hurt.

> It might get unzeroed if you work with the memory.

Maybe, but it isn't very common. I'm not sure when the C standard allows changing padding bytes, but in practice the compilers I've used don't seem to do it. And again, it's just a debugging aid, if it causes too much trouble on some platform, just turn it off.

btrask··on What is your favorite C programming trick? (2009)
It's defensive coding. Do you think defensive driving is 'sweeping problems under the carpet'? (It is, but it's still useful...)

I use every tool at my disposal. Sanitizers, static analyzers... and also not leaving dangling pointers in the first place. Why would I do anything less? It doesn't cost anything except a little effort.

Take a look at this recent HN link: https://www.radsix.com/dashboard1/ . Look at all those use-after-free bugs. Even if it only happens 1% or 0.01% of the time... It's a huge class of bugs in C code. Why not take such a simple step?

btrask··on What is your favorite C programming trick? (2009)
Well, dangling pointers are also easy to forget... Yes, it requires some discipline. Good code requires discipline, doesn't it?

The trick of checking that buffers are zeroed is purely a debugging tool, so it's okay if it doesn't work on some platforms. And if you allocate with calloc(), the padding will be zeroed for you. It's actually very rare that you will have to call memset() with this technique.

btrask··on What is your favorite C programming trick? (2009)
Here's a trick that will actually help produce more secure and reliable programs.

    *outArg = myPtr; myPtr = NULL;
    free(aPtr); aPtr = NULL;
Set your pointers to null when you free them! Set them to null when you transfer ownership! Stop leaving dangling pointers everywhere!

Some people say they like dangling pointers because they want their program to crash if something is freed when they don't expect it to be. Good! Do this:

    assert(ptr);
There are also many more tricks you can do once you start nulling pointers. You can use const to mark pointers that you don't own and thus can't free. You can check that buffers are all zero before you free them to catch memory leaks (this requires zeroing out other fields too of course).

Please, null out your pointers and stop writing (most) use-after-free bugs!

btrask··on Zero-Days in Desktop Web Browsers
Well, they tried to write a new browser engine in Rust but gave up and got laid off. A few pieces got integrated into Firefox but the browser is still wildly insecure (cf. the article).

Turns out "Rewrite it in Rust" is actually really hard when you have millions of lines of code. Even Google probably can't rewrite Chrome from scratch.

Maybe if we just try harder, communism will work. You gotta draw the line somewhere.

btrask··on Zero-Days in Desktop Web Browsers
They tried that. It was called Servo, and it was Rust's raison d'etre. It failed.
btrask··on The accidental genius of Yo
Guys, I worked it out. It's the Heisenberg uncertainty principle/Fourier conjugate.

Let's say you send a yo now, and then you're going to send another one in 5 minutes. Then you decide to send a third in between. How much information does it contain? Less than a full timestamp's worth, because the timing is constrained.

Once you are sending yo's at the maximum line rate (certainly at least every nanosecond, it's such a critical piece of infrastructure), sending or not sending an individual yo is down to one bit of information. The time component is basically completely gone.

In other words, you cannot know the precise position of a yo at the same time as knowing the precise momentum.

Page 1 of 11Next →