Hacker News

Top stories

Live mirror
30 storiesupdated just nowView source snapshot
  1. F-Droid 2.0(f-droid.org)
    90comments
  2. Two-tier encryption in the UK(macanorak.com)
    246comments
  3. Show HN: Whiteboard (YC W26) – an open-source IDE for thoughtful software design(github.com/devdotfast)
    discuss
  4. Nokia Design Archive (2025)(aalto.fi)
    92comments
  5. Agents.md speaks Unix, and you should too(fmind.dev)
    discuss
  6. WaveDigger: Dig into wireless signals to discover their physical locations(github.com/christianrowlands)
    3comments
  7. GitHub has not removed malicious imitation software after 3 weeks(successfulsoftware.net)
    42comments
  8. B5-BJ2 – Ice Cream Barges – Concrete Ship Constructors (2023)(thecretefleet.com)
    1comments
  9. Linux support is coming to Snapdragon X2 series(qualcomm.com)
    240comments
  10. Experiencing writing at our recent Chinese calligraphy workshop(viewsproject.wordpress.com)
    1comments
  11. Federal judge orders Texas to air condition all prisons by the end of 2029(texastribune.org)
    35comments
  12. The science of Monkey Island: can grog dissolve a metal mug that fast?(jgeekstudies.org)
    16comments
  13. Ideas on modernizing the open-source desktop(lwn.net)
    408comments
  14. RAM: the forgotten history (2024)(coredump.cx)
    2comments
  15. When the Debugger Lies(danielmangum.com)
    17comments
  16. ArXiv receives multiyear commitments to support it as an independent nonprofit(arxiv.org)
    38comments
  17. Enjoy Every Sandwich(bradmontague.substack.com)
    66comments
  18. Coulomb's law remains tricky to test at home(chillphysicsenjoyer.substack.com)
    15comments
  19. The newest ESP32 can run Linux and it's getting close to a Raspberry Pi(xda-developers.com)
    74comments
  20. VSCode's SSH Agent Is Bananas (2025)(fly.io)
    188comments
  21. Contrastive Language Models(contrastive-lm.notion.site)
    41comments
  22. Oracle invokes force majeure on New Mexico AI data center(qz.com)
    1comments
  23. The "Windows XP Box" (2003)(mini-itx.com)
    44comments
  24. Fixing the Portobello Police Station Clock(pointinthecloud.com)
    112comments
  25. The Year of Internal Tools(geocod.io)
    19comments
  26. LinkedIn wins court order blocking mass scraping of user data(therecord.media)
    27comments
  27. Hackers influence ChatGPT and Gemini to direct users to scam centers(medium.com/arielsimon)
    38comments
  28. What Is RLCD? The Secret Behind Jev(di-zhang-llm.github.io)
    6comments
  29. Owners mourn spoiled food after firmware update bricks Samsung smart fridges(arstechnica.com)
    221comments
  30. Dynamic Abliteration: Non-Destructive Refusal Suppression via Engram Steering(blog.madhukaraphatak.in)
    32comments

When the Debugger Lies

54 pointsby 2d agodanielmangum.com
17 comments
1d agoHN ↗

Nice writeup. WinDbg has the same stale-cache trap on live Windows targets.

4h agoHN ↗

Once upon a time I had to figure out an issue where I forgot a `return` statement at the end of a non-`void` function, so the C++ compiler happily omitted both RETs for some reason and let the program go straight into illegal instructions. That was fun to debug (not fun, I practically had to single-step through the entire program) because every time this happened the debugger was incredibly confused about what the fuck was going on and nothing made any sense.

3h agoHN ↗

Another issue that happened in the same project is that for some reason whenever I compiled it with a regular C++ compiler, field writes were disappearing into the abyss. I think I actually never figured that out because it was literally the same object at the same memory address, there were no other threads and yet when a subroutine returned after writing the field, the write disappeared?? The strangest thing is that Emscripten's C++-to-WASM cross-compiler worked perfectly fine with the exact same routines. I wonder if the compiler I used simply had fuckass issues, it was an oldish (by modern standards) Apple clang from like probably macOS 10.14 or so.

3h agoHN ↗

That or you hit some UB elsewhere that caused the compiler to assume things that you didn't follow.

Trying UBSAN and ASAN might have been worth it. I don't think comparing debug and release builds would have helped: could be buggy optimisations or UB in your code regardless of what the outcome of that test was.

3h agoHN ↗

In this case I was reading memory with a debugger and could see that it literally was the same object at the same memory address, but what I did not know was whether or not different parts of the code had different views of that field for some reason, or any number of other things that could have been causing the issue. Either way, it was super weird and frustrating.

2h agoHN ↗

The right tool for that occasion would be a watchpoint.

1. You check in both places in code in the debugger that the address of the field matches. (Maybe the object is at the same address, but due to some build system level ifdef mismatch, you effectively get different struct definitions in different places or something like that.)

2. You add a breakpoint inside the procedure and outside it.

3. When the breakpoint inside is hit, you add a watchpoint at the address of the field. Continue. See if the watchpoint gets hit before reaching the second breakpoint.

3h agoHN ↗

It makes no sense to me that C and C++ didn't require a diagnostic for this, rather you hit UB.

I know that at least modern GCC and Clang will warn and/or error for this (not sure which as I use -Werror), but still, this is pointless UB to have.

And no, in this case I don't buy that a C90 compiler would have been unable to check this.

3h agoHN ↗

I think I was using C++14 at the time...

3h agoHN ↗

It seems like something that could have been trapped right in k&r.

Was it ever even theoretically under any circumstances for any reason intended to be able to write a stack of functions with no returns that just fall into each other like assembly? I can't believe it.

So it seems like something even the very first compiler could have cought right in an early parser pass or stage.

But I also decline to believe I have a better idea about something than K or R, so there must be a non-triviality I don't see. I mean goto() exists in the language so ?

... I guess simply detecting the end of a function, or detecting that the process reached the end of a function, isn't a good enough definition of the problem. You can have any number of returns or gotos in the middle that you are always supposed to hit, and intentionally no return at the end because instead you have an assert or a goto.

assert you should never get here, goto error, goto not error but just next step, etc. They might or might not be error conditions that the process reached that spot, but it's not an error that the code doesn't end with a return.

3h agoHN ↗

Having been involved in the WG14 discussions on this topic:

The issue is that there is a contingent of users who complains about cases where the return dynamically can't be hit but that isn't obvious statically. Consider something like this:

  int do_something(enum meow koala) {
    switch (koala) {
    case enum_val_1: return 5;
    case enum_val_2: return 3;
    /* etc., covering all the enum values */
    }
  }

Should this be required to diagnose? That's the sticking point.

2h agoHN ↗

There may be differences between C and C++ here (and I worked with C++ more recently than C), but: if that enum doesn't specify an underlying type it would be UB to have a value that isn't in the "member list" of the enum. In that case it should be possible to determine if all cases are covered.

If an underlying type is specified, then it should error since it is legal to have those values (unless the whole range of the underlying type is covered by the cases.

Again, that is what would be sensible from a C++ perspective, I don't know if C differs here.

EDIT: Also, and now I'm talking with my Rust user hat on: it is better to not have pointless UB. Yes some is needed to practically allow for optimisation. But C and C++ had a lot of UB that doesn't really help with making your code faster, such as this.

2h agoHN ↗

Again, that is what would be sensible from a C++ perspective, I don't know if C differs here.

In C it is not UB for an enum to have an integer value that does not correspond to any listed enumeration constants.

51m agoHN ↗

I don't think your C++ comment is true, otherwise you wouldn't be allowed to OR together C enums. I think the restriction is on values wider than the underlying type, where the underlying type is always wide enough to support any representable bit pattern.

4h agoHN ↗

Very cool! I love reading about details like this.

1h agoHN ↗

Reminds me of the time when visual studio would show one value of a variable, but print would show a different one. Never trusted VS again after that.

34m agoHN ↗

Debuggers can lie pretty often. Especially if you are just doing things with ASM. I had some issues with V8 debugging and the debugger just saying that a function got called which for sure wasn't. Even with the option that V8 should emit gdb info :/