[HN Gopher] Eliminating Data Races in Firefox ___________________________________________________________________ Eliminating Data Races in Firefox Author : caution Score : 319 points Date : 2021-04-06 15:28 UTC (7 hours ago) (HTM) web link (hacks.mozilla.org) (TXT) w3m dump (hacks.mozilla.org) | wyldfire wrote: | > What is ThreadSanitizer? ThreadSanitizer (TSan) is compile-time | instrumentation to detect data races according to the C/C++ | memory model on Linux. It is important to note that these data | races are considered undefined behavior within the C/C++ | specification. | | TSan, ASan, UBSan - if you are writing code and your toolchain | supports these, you should use them. Over the past 6-7+ years | I've used them, I have never seen a false positive (I'm sure some | have occasionally existed but they seem rare in practice). | | > However, developers claimed on various occasions that a | particular report must be a false positive. In all of these | cases, it turned out that TSan was indeed right and the problem | was just very subtle and hard to understand. | | Yes, I have seen this phenomenon! | inetknght wrote: | Address Sanitizer -- never seen a false positive. Ever. | | UBSan -- again never had a false positive. | | Thread Sanitizer _does_ have false positives in some | circumstances. They 're hard to verify to be falsy and in many | ways it's better to refactor to eliminate the complaint because | you'll end up with better cleaner code. For example, Qt uses | those _atomic fences_ that the article describes [0] [1]. | | [0]: _TSan does not produce false positive data race reports | when properly deployed, which includes instrumenting all code | that is loaded into the process and avoiding primitives that | TSan doesn't understand (such as atomic fences)._ | | [1]: https://lists.qt- | project.org/pipermail/interest/2014-March/0... | derf_ wrote: | I have seen false positives in ASAN. | | In Firefox, media threads use a reduced stack size (128 kB), | due to, historically, 32-bit address-space concerns with lots | of media elements on a page. Opus, in its default | configuration, requires a fair amount of working stack memory | (a few dozen kB in some cases). "A few dozen" is much smaller | than 128 kB, but apparently enabling ASAN increases the stack | usage, quite a bit. So we got crashes under ASAN when it | overflowed the stack that would not have been possible | without ASAN enabled. | | https://bugzilla.mozilla.org/show_bug.cgi?id=750231 | inetknght wrote: | Address Sanitizer inserts sentinels on the stack to watch | for certain kinds of dangerous stack behavior. I would be | willing to bet that the stack overflow _could_ occur | without ASAN and it 's not a false positive. | derf_ wrote: | You are right to be concerned. The primary culprit is the | use of C99 variable-length arrays (or alloca when those | are not available). I can see why ASAN would want to pad | those. | | Fortunately, the allocation sizes of these arrays are | tightly constrained by the limits of the Opus format | (this is not an accident: I helped design the format). I | performed a careful analysis (by hand) to ensure the | maximum possible stack usage (without ASAN) was not | anywhere close to the size allocated for the stack. It is | of course possible that I made mistakes, but I tried very | hard not to. | | The broader point is that this is an entire class of | memory access error that ASAN _cannot_ properly validate | due to its design. Because it changes the system under | test in ways that differ from a real deployment, I cannot | use it to mechanically validate my hand analysis. | | It is worth noting that valgrind does not have this | problem (because it instruments the original binary, | instead of making compile-time changes), and is also used | by Firefox in testing. | inetknght wrote: | Address Sanitizer isn't a tool that solves every problem. | But it solves well the problems it's intended. | | I'm assuming you're still talking about Firefox running | Opus [0]? I'm not familiar with it. But I do think that | any platform that can run Firefox and wants to listen to | audio should have _a lot_ more than 128k lying around. | Otherwise your user isn 't using the right tool for the | job. | | I understand memory constraints can be tight and it feels | like there's 128k of space _right there_ that you can | use. And to achieve that you 've written it in C and | manually calculated the stack space needed. It feels | _awesome_ to have that kind of knowledge and experience | with opportunity to leverage it! It 's great that you've | helped design a media format and implement something to | process it! | | But Firefox wastes tons of _megabytes_ just to load, | store, and transmit telemetry, preferences, search | providers... the list can go on. Do you really want to | try to convince me that a 128k slab for audio that the | user specifically loaded is too expensive in the face of | all of the telemetry loaded by Firefox these days? | | Why add all the maintenance headache when you can instead | allocate a single slab for your own use? If I were to | write it and manually optimize then I'd use an allocated | slab. And, as a bonus, the slab's ownership can move to | any other thread if needed. And it would make it clean in | Address Sanitizer. And, even more important, I wouldn't | have to worry about what happens if the frames before my | entrypoint changes. For example, Firefox's software | design could change and adds a couple of wrappers around | the manually-sized stack. What happens if I want to | compile Firefox on a different platform which doesn't | permit a manually-sized thread stack? | | So it sounds like you've written something that's going | to be very difficult to maintain if you were to vanish. | And you've written it for a software product where that | level of optimization is, perhaps, better done | automatically by tools available to you. | | If you build a standalone media player specifically for | Opus then that'd be pretty cool. But Firefox shouldn't | have pieces that are difficult to maintain. | | [0]: https://hacks.mozilla.org/2018/10/introducing- | opus-1-3/ | nyanpasu64 wrote: | I've gotten false positives in ASan when trying to instrument | a Win32 application code compiled in MSVC using MSVC's then- | experimental ASan support, using the wrong combination of the | maze of ASan libraries (static library combined with dynamic | MFC). And I also get startup crashes when running MSVC ASan | binaries in Wine. But it's obscure beta use-cases and some | may be fixed by now. | perryizgr8 wrote: | > Yes, I have seen this phenomenon! | | I've had this happen to me personally. Looking again and again | at the tsan error and the code it pointed to, I was absolutely | sure it was a false positive. Thankfully I got a friend to look | at it and after a good night's sleep he was able to explain to | me how exactly the code was wrong. | | Tl;dr: It is extremely hard to write correct threaded code in | C/C++, and it is quite hard to recognize errors even when they | are pointed out to you. | CodeBrad wrote: | In my opinion, the main limitation of TSan is that it cannot | find all possible races. (An impossible task so I think TSan is | a pretty great tool to get to the point that this is the main | limitation) | | As a dynamic tool, if a race is observed during execution by | TSan, the race is very likely to be real. But it is impossible | to "observe" execution for every part of a large code base, and | so real races are likely still hiding in some edge case that | TSan did not execute. | | Static Analysis tools are interesting in that they have the | opposite problem. Static tools can detect races across the | entire code base, but without runtime information it is | difficult to know if the races are real. This leads to more | real races being detected, but also comes with more false | positives. | | There is a lot of interesting working being done on data race | detection and how we can bring these two sides closer together | to find more real races, without overwhelming developers with | false positives. | inetknght wrote: | > _In my opinion, the main limitation of TSan is that it | cannot find all possible races._ | | In my experience TSan finds all possible races if it's built | with unit tests and unit tests provide enough coverage. If | unit tests don't provide enough coverage then there are | likely other bugs lurking beyond just data races. | CodeBrad wrote: | I agree, good code coverage can probably get most of the | way there. But there are some problems with relying on | coverage. | | Coverage can be misleading. Maybe there is some function | being executed in parallel: int global; | void foo() { int local; if | (complex_condition) bar(&local); else | bar(&global); } | | And assume maybe somewhere way down the call chain the data | passed to bar is modified. The bar function and all of the | functions called in bar can have 100% test coverage, but if | the else branch is not covered, the race will be missed. | | So without true 100% test coverage, it is possible races | are being missed by dynamic tools, and true 100% test | coverage is probably not possible or feasible in large | complex projects. | inetknght wrote: | > _but if the else branch is not covered, the race will | be missed._ | | Yes. | | > _true 100% test coverage is probably not possible or | feasible in large complex projects._ | | I have yet to encounter a single large complex project | where 100% test coverage is not possible. I _have_ | encountered such projects where 100% test coverage | required massive refactoring of the code to facilitate | testing and doing so resulting in fixing most customer | complaints received. | tsimionescu wrote: | So you truly believe that Firefox or Windows or Ubuntu | could not only be 100% covered by unit tests, but that it | would actually be worth taking the time to do so? (edit: | typos) | inetknght wrote: | Yes, I firmly believe that Firefox, Windows, and Ubuntu | can achieve 100% unit test coverage of software. I truly | believe it would be worth its while. | Yoric wrote: | As someone who has worked on the code of Firefox, I | strongly doubt that. | | For instance, pretty much every piece of code (whether | native or JS) I've seen is programmed defensively, | assuming that for some reason invariants can be broken - | something that typically cannot happen unless there is a | memory corruption involved. Testing all these defensive | programming branches is not possible without introducing | memory corruptions. | nitwit005 wrote: | Unit tests tend to be written to run without parallelism, | or at least with less parallelism than the normal app has. | hedora wrote: | Not my unit tests. :-) | tene wrote: | I've never actually used TSan, so please correct me if I've | missed something significant about how it works, but | doesn't TSan need to observe the race happening in order to | detect it? | | The code coverage analysis I've seen in the past has only | evaluates what code is run at least once, but how do you | get coverage analysis to evaluate the coverage of what code | runs concurrently with what other code effectively enough | to get confidence that you'll detect data races? | | For example, if you've got a cache that safely handles | concurrent use for most operations, but has a data race | when two threads both cache miss on the same key within a | short window of each other, are there kinds of code- | coverage analysis that could theoretically point out that | none of your tests involve a cache miss of the same key in | two different threads? | | I've seen concurrency permutation testing tools, that can | reorder the sequence of operations between different | threads searching for a permutation that causes a data | race, but that relies on actually executing the | potentially-racy behaviour at all during testing, right? | | I guess this is also what fuzzing is about, but are there | tools or techniques you can use to increase your confidence | in how well your tests cover the space of concurrent use of | your data structures? | steveklabnik wrote: | TSan uses run-time instrumentation, yes. | BlueTemplar wrote: | Pff, I always suspected that they were a bunch of racists... | dang wrote: | Please stop posting unsubstantive and/or flamebait comments to | HN. It looks like you've been doing it a lot, and it's not what | this site is for. | | https://news.ycombinator.com/newsguidelines.html | BlueTemplar wrote: | Well, it was supposed to be a joke, but I now realize that it | was in bad taste, so I apologize. | xvilka wrote: | Do they have a roadmap for complete Firefox conversion to Rust? | steveklabnik wrote: | It's been a while, but I don't believe that is a goal, so I | don't believe there's a roadmap for it. | stjohnswarts wrote: | I think you should change your question to "which -parts- of | firefox will be redone in rust and is there a road map for | that?" | jdashg wrote: | The current roadmap for that is "never". :) There just isn't | enough ROI for rewriting all old code. | villasv wrote: | I'd go further and say that the ROI is not only | "insufficient", it is negligible. Unless your legacy code is | written in a language/framework where available experts are | disappearing (which is not the case here), there is | practically zero value on rewriting code that works as | intended. | zozbot234 wrote: | Plenty of legacy code was reimplemented from C++ to Java (a | memory-safe language, not unlike Rust) when the latter was | released. The ROI is definitely there. But given the scale | of that task, it makes sense to pick the lowest-hanging | fruit first. AIUI, most of the effort wrt. "oxidation" is | now around WebRender, specifically making it the default | render backend. | jhgb wrote: | Surely at one point the return for getting rid of the rest of | the C++ code would be getting rid of the C++ build process? | est31 wrote: | > Overall Rust appears to be fulfilling one of its original | design goals: allowing us to write more concurrent code safely. | Both WebRender and Stylo are very large and pervasively multi- | threaded, but have had minimal threading issues. What issues we | did find were mistakes in the implementations of low-level and | explicitly unsafe multithreading abstractions -- and those | mistakes were simple to fix. | | > This is in contrast to many of our C++ races, which often | involved things being randomly accessed on different threads with | unclear semantics, necessitating non-trivial refactorings of the | code. | WalterBright wrote: | D takes a different approach. D has a type constructor | `shared`. Only types marked as `shared` (or `immutable`) can be | accessed by multiple threads. If you've got concurrency | problems, the scope of the problems are immediately reduced to | the subset of the code typed as `shared`. | | In addition, `shared` types cannot be accessed directly. They | can only be accessed via library routines, such as D's atomic | library. | | Having an `immutable` data type also helps, as immutable data | can be accessed by multiple threads without need for | synchronization. | eximius wrote: | It's not that different. Rust has Sync + Send + &refs and | &mut refs. | secondcoming wrote: | Does this approach have to deal with potential recursive | locking? | WalterBright wrote: | Not by itself. But D's prototype ownership-borrowing system | can help with that. | d110af5ccf wrote: | Did D ever get around to specifying a formal memory model? | Because when I tried to adopt D a couple years ago I felt | there was a lot of ambiguity surrounding the semantics of | `shared`, particularly when interfacing with C and C++ code. | | I ended up just casting to and from `shared`, and that | _seemed_ to work, but it was pretty verbose for highly | parallel code and I was never quite sure under what | circumstances doing that might violate the compiler 's | invariants. | | Also such casting appeared to eliminate most of the benefits, | since what appeared to be local data might have been cast and | had a pointer sent across to another thread elsewhere. In the | end `shared`, @nogc antics (the language internals weren't | fully annotated), closures requiring the GC (compare to C++), | and the friction of interfacing with highly templated C++ | code such as the Eigen library caused me to abandon the | attempt. I sure learned a lot in the process though! | aliceryhl wrote: | That description seems very similar to how Rust's type system | enforces thread safety. You have two kinds of references: | shared and exclusive. The shared references will typically | only provide immutable access, whereas if you have an | exclusive reference, you can mutate it. Beyond this, there | are some special types that can be mutated through shared | references, e.g. the AtomicI32 type. Similarly, the Mutex | type lets you lock it given only a shared reference and | provides you with an exclusive reference when locked. | kibwen wrote: | And when it comes to finding bugs in your unsafe concurrency | primitives in Rust programs, there is a tool called Loom that | helps with that, as a powerful complement to what | ThreadSanitizer provides: https://github.com/tokio-rs/loom . | You can think of Loom sort of like QuickCheck, except the | permutations are all the possible thread states of your program | based on the memory orderings that you have specified. | | Here's a video that briefly talks about what Loom can do | https://youtu.be/rMGWeSjctlY?t=7519 (it's part of a larger | video about memory orderings, and is a great introduction to | the topic). | gamegoblin wrote: | Loom is really awesome, though it is focused on exhaustive | testing, so not suitable for code that has a lot of possible | interleavings (e.g. due to a ton of threads, or a large body | of code). | | There is a new project out of AWS called Shuttle [1] which is | like Loom, but it does random exploration instead of | exhaustive exploration, which enables massively distributed | testing of really complicated stuff. | | [1] https://github.com/awslabs/shuttle | kibwen wrote: | Excellent, thanks for the tip! I have to ask though, given | a tool that does exhaustive testing (like Loom), shouldn't | it be trivial to adapt it to do random testing merely by | randomizing rather than enumerating the test inputs? Is | there something more going on that I'm not seeing? | wyldfire wrote: | Is there anything like Loom or Shuttle for C/C++? | | Or are these only implemented in rust and they'd still work | with C/C++? | evmar wrote: | It's interesting, I read this and had the opposite conclusion | -- people are still writing racy code using Rust. | | I mean, it's great that you can write threaded code with more | confidence, but it seems the conclusion here is that Rust gives | you _more_ confidence but not _absolute_ confidence and you | still need the normal stable of runtime detection tooling. The | second fix[1] in particular resembles the bad pattern of | "sprinkle atomics it until it works" you see in non-Rust | languages. | | (If this comment raises your hackles, please read the "no true | Scotsman[2]" fallacy before responding.) | | [1]: | https://hg.mozilla.org/integration/autoland/rev/044f8b594c71 | [2]: https://en.wikipedia.org/wiki/No_true_Scotsman | fluidcruft wrote: | Is that "sprinkle atomics" stuff in bindings/interfaces for | non-Rust external code? I'm not particularly surprised that | you would have to wrap atomics around externalities and not | doing that would be a source of errors if the external code | has race conditions. | evmar wrote: | It's not, I linked the patch. (I don't fully understand the | patch so I'm happy to be corrected here, but it looks like | it was an ordinary "use atomics incorrectly" bug.) | dan-robertson wrote: | Another fallacy to keep in mind is that two things not being | perfect does not make them equal failures. | est31 wrote: | You are correct. The "no data races" slogan of Rust is | accurate but you need to mention the way it needs to be | understood. First, data races are only a subset of all race | conditions. Second, like the other safety guarantees, the | statement only applies to safe Rust. Once you use unsafe Rust | or any non-Rust language (and both usually happens in any non | trivial program), this guarantee stops being a guarantee. But | it doesn't mean it vanishes into nothingness. It instead | becomes a quantitative statement: it's much easier to avoid | data races in Rust than in unsafe alternatives. | | I think when you build Rust projects that require | reliability, it's foolish to lean back and believe that | marketing slogan and not look for concurrency bugs. However, | once you found them, it's way easier to fix them, at least | when your unsafety is well encapsulated like how it's | recommended. | | I think the big challenge for Rust in this context is to | improve its tooling so that using it is comparable or even | easier than the C++ tooling. This blog post is proof that | such tools should be ran otherwise you are missing out on | important bugs. | coliveira wrote: | I think the mistaken idea that Rust allows "bug free" | multithreaded programs will lead to a new generation of | difficult to maintain multithreaded software... The lesson of | multithreading should be that you need to use less of it and | only when necessary, not that you should write more. It is | similar to what we got when Java was the darling against C++: | you now have lots of Java programs that don't have the same | problems as the C++ version, but still are difficult to | understand, leading to the well known FactoryFactory | syndrome. | mplanchard wrote: | I honestly don't see "less concurrency" as a viable route | for modern software. We're adding cores at a much faster | rate than we're improving clock speeds. Anything that makes | concurrency easier is a win in my book. | coliveira wrote: | There are several ways to increase concurrency: low level | and high level. UNIX, for example, provided high level | tools for concurrency (processes). You can also use | message passing if you want. It is possible to write more | concurrent software using safer primitives, instead of | relying in low level techniques such as Rust/C++ | multithreading. | tsimionescu wrote: | I don't think it makes sense to call processes either | higher or lower level than threads. Splitting your | program into multiple processes often comes with many | other drawbacks than spitting it into multiple threads. | You can even still have data races if you use files or | mmap to communicate between processes (you can also get | something similar even with pipes/sockets for complex | chunked data structures). | | Even worse, there are very few, if any, tools that could | help you analyze a multiprocess program for any kind of | race conditions. | brundolf wrote: | > What issues we did find were mistakes in the | implementations of low-level and _explicitly unsafe_ | multithreading abstractions | | (emphasis mine) | | The important thing is that the races only happened in unsafe | { } blocks. It's well-established that these blocks should | basically be treated like C++ in terms of scrutiny, but (I | believe) you can still have roughly "absolute confidence" in | non-unsafe code. | | It's true and interesting that unsafe { } blocks deserve | sanitization analysis like C++ code does - and maybe this | hasn't been discussed enough - but I don't think it's fair to | suggest that the enormous language benefits are outweighed by | some false sense of confidence. The proportions in that idea | just seem way out of whack. | benschulz wrote: | AFAIU one can create races in safe code using atomics with | insufficient ordering. | | (That notwithstanding, I agree that Rust is a vast | improvement over C/++.) | steveklabnik wrote: | "races" is too general. Safe Rust cannot have _data | races_. It can have _race conditions_. | benschulz wrote: | I'm not convinced this is a meaningful distinction in | this context. Assuming a developer consciously creates a | race which turns out to be a bug, how does it matter | whether it was a data race or some other kind of race | condition? | steveklabnik wrote: | Data races are undefined behavior, and race conditions | are a logic error. Yes, both are bugs, and both are | important to fix. But they have (at least to me) | different severities. | | (Worth noting that data races have a clear, unambiguous | definition, and therefore are possible to eliminate | through tooling. Race conditions rely on program intent | or logic, and are therefore... not really.) | | Also, I think it matters, generally, that we are truthful | about what Rust prevents and does not prevent. | brundolf wrote: | > Worth noting that data races have a clear, unambiguous | definition, and therefore are possible to eliminate | through tooling. Race conditions rely on program intent | or logic, and are therefore... not really. | | This is a great point. Usually people only talk about the | two categories in terms of vague severity, but this is a | hard distinction which has lots of implications for how | each can be dealt with. | [deleted] | bcoates wrote: | In general data races can break program invariants, | violate memory safety and do other undefined behavior. | | In C++, data races can cause jumps to invalid addresses | and the compiler will assume data races away and delete | checks that are redundant in the single-thread case. The | equivalent problem happens in most languages where data | races are possible (two Python threads writing at once | can put a value into an impossible/illegal state) | | An ordinary race condition is just an observable effect | of the nondeterministic progress of threads, so it's | possible to have a truly benign race condition, so long | as the correctness of the whole program doesn't depend on | the outcome of the race. I/O causes nondeterminism | anyway, so it's not really practical to avoid all | ordinary races. | anp wrote: | "This context" is the original article, which is | discussing data races specifically. | volta83 wrote: | You can also create races in safe Rust by using the file | system, no concurrency primitives necessary (just create | a new file, close it, and re-open it assuming it's still | there..). | | What safe Rust doesn't have is _data races_. | stjohnswarts wrote: | They literally found tons of new races conditions in c++ and | 2 in the rust code with their tool. And you want to act as if | that little factoid makes rust useless somehow. Anyone who | thinks a language is flawless is not thinking correctly and | that includes rust. However it does a much better job at this | than C/C++ yet somehow you twisted that into declaring rust | as useless. | evmar wrote: | I'm not sure how you got from "Rust gives you more | confidence but not absolute confidence and you still need | the normal stable of runtime detection tooling" to | "useless". | frenchy wrote: | It's probably because "Rust gives you absolute | confidence" is a strawman, I don't think anyone was | arguing that, and often people's first reaction to a | strawman is to construct a contrary strawman. | agumonkey wrote: | hopefully it will lead to a new borrow checker logic | chowells wrote: | Yeah, that was the part that stood out to me as well. I thought | it was pretty intuitively obvious that having your data races | confined to small segments is better than allowing them to be | spread over the entire codebase, but a lot of people act like | it negates the advantage of working in a safer language | entirely. It's nice to have empirical reports that back up the | "obvious" though. Sometimes "obvious" things turn out to be | wrong. It's always good to check them. | setr wrote: | > but a lot of people act like it negates the advantage of | working in a safer language entirely. | | I think the underlying assumption is more along the lines of: | the easy cases are made easier, and the hard cases are made | impossible -- or rather the concern being that rust hasn't | made the problem easier, it just moved it around. | | Which is often the case with claims of solving long-lasting | problems | stouset wrote: | > I think the underlying assumption is more along the lines | of: the easy cases are made easier, and the hard cases are | made impossible -- or rather the concern being that rust | hasn't made the problem easier, it just moved it around. | | Except in this case the article linked demonstrates that | they've made things dramatically easier overall. Data races | went from being endemic in a C++ codebase to being in a few | low-level and easy-to-locate areas. | | The easy stuff stayed easy, the bulk of the rest was folded | into the easy case, and even the hard cases appear to have | been made easier to find, identify, and fix. | Quekid5 wrote: | Once you pick away enough at the straws, the needle | becomes a lost easier to find. | pdpi wrote: | Not all forms of moving things around are equivalent. Some | just keep the problem as diffuse as it was before, others | restrict the problem to a smaller area. | | Rust does not, by any means, solve this problem. What it | does do is help you prove that the problem is contained to | a smaller subset of your codebase that you can audit/reason | about much more easily. | kibwen wrote: | _> the concern being that rust hasn't made the problem | easier, it just moved it around._ | | This is largely the point of Rust, though. Rust takes | problems that used to manifest at runtime and causes them | to manifest at compile-time, shortening the feedback loop | drastically. It also takes problems that used to manifest | all over the codebase and roots their causes in the leaf | nodes of the program that are making use of `unsafe` | blocks. Moving around the problem turns out to be a | valuable way of addressing the problem, without ignoring | any of the essential complexity or making anything | fundamentally impossible. | wtetzner wrote: | > shortening the feedback loop drastically | | More importantly, forcing you to catch them. Problems at | runtime don't get caught until that condition actually | occurs during an actual run of the software. | chriswarbo wrote: | > Which is often the case with claims of solving long- | lasting problems | | This is what I really like about programming language | theory: problems which are literally undecidable in | existing languages, can be made almost _trivial_ by | designing a language with that problem in mind. The trick | is to have the language keep track of the information | needed for the solution, so we 're not dealing with "black | boxes". | | A classic example is annotating every variable with a type, | and propagating that information through compound | expressions; lets us spot problems like trying to use a | number as a string, without worrying about the halting | problem (we do this by forbidding some technically-valid | programs, like `1 + (true? 10 : "hello")`). | | Of course, this leaves the much harder problems of (a) | keeping the burden imposed by this extra information down | to a reasonable level, and (b) trying to make the language | compelling enough for people to actually use. Rust is one | of the few examples of going all-in on a new ecosystem, and | it actually being embraced. Often it's easier to "embed" a | new language inside an existing language, to piggy-back on | the existing tooling (e.g. the variety of auto- | differentiating languages built in Python) | Quekid5 wrote: | Yes, people often forget that TMs really are "pure | runtime". Sure, the program itself is static, but nothing | else is. There's no imposed semantics on _anything_ | beyond the pure mechanism of the interpreter itself. This | lessens the 'problem' part of the Halting Problem | drastically if you just impose some constraints on the | programs, e.g. static types, maybe a borrow-checker, etc. | [deleted] | ChiefOBrien wrote: | Who knew using already existing data race analysis tools is much | more feasible than shoehoning a huge project into a brand new | language. Way to go mozilla! | Jweb_Guru wrote: | If you believe that this tool has found all the data races in | the C++ code, or even a majority of them, I have a bridge to | sell you. | ChiefOBrien wrote: | Oh come on now. If it was really important for them then why | did they chose C++ a long time ago after deciding to rewrite | Netscape from scratch? Their history is full of dumb choices | and now suddenly going full Rust is the most important thing | because... the codebase is lousy? It's not gonna bring back | any new/old users, and right now the web needs a healthy | marketshare. | dang wrote: | Hey, could you please not take HN threads into flamewar, | including programming language flamewar? It's tedious, and | one reason this site got started was to have a forum that | avoids that kind of thing. | | Thoughtful critique is welcome, but that would require (a) | adding solid information, and (b) taking out the swipes. | | https://news.ycombinator.com/newsguidelines.html | steveklabnik wrote: | > now suddenly going full Rust is the most important thing | | As said above, Mozilla does not seem to have ever | suggested, in the past or now, that "going full Rust" is a | goal, let alone "the most important thing." | ChiefOBrien wrote: | Yeah and Webrender, Stylo, and Servo just happen to | appear out of thin air. | steveklabnik wrote: | Webrender and Stylo were big projects, but they're | already in tree, and that means about 10% of Firefox is | Rust. That's hardly "full Rust." | dralley wrote: | Firefox has something like 8 million lines of C++. Stylo | replaced about 150,000 lines of that, and WebRender is | more of a fast path than a true replacement of anything. | | Both of those rewrites came with massive speedups due to | the amount of parallelism they were able to use, which | was impractical in C++. Other parts of Firefox are not as | critical or parallelizable, hence why they aren't being | replaced any time soon. | | You seem to be quite aggressively misinformed, if you are | not deliberately trolling. | ChiefOBrien wrote: | > the amount of parallelism they were able to use, which | was impractical in C++ | | You mean after not using OpenMP, basic multithreading | core guidelines, and not doing the refactoring with | sanity checkup in TLA+, tools that end up on the | frontpage everytime people rediscover them. | Yoric wrote: | Out of curiosity, have you used OpenMP or TLA+? I seem to | remember that solve problems that are really, really | different from the use cases for which Rust is designed. | dralley wrote: | Please a more productive use of time than constructing | ridiculous strawmen on the internet. ___________________________________________________________________ (page generated 2021-04-06 23:00 UTC)