Rendered at 12:32:21 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
amluto 16 hours ago [-]
Sadly the PR gets a detail wrong:
> Implementations are expected to optimize the code generated to be as minimal as possible for the platform. For example, on X86 it’s expected that this produces a single INT3 instruction. The goal in this expectation is to place the debugger as close as possible in the caller of breakpoint() to improve the debugging experience for users.
This is the wrong design on x86 at least with many debuggers. x86’s int3 is a trap and reports the address of the next instruction in the saved register state [0]. Most debuggers are not very clever and just use the saved address to generate the offending line of code and the call stack. But if the trap sequence is just int3, then the saved address could be outside the offending basic block or even outside the function entirely. gdb is certainly in the class of debuggers that get this wrong.
The easy workaround is to generate int3; nop for the breakpoint instead of just int3. The saved address will point to the nop and the debugger will be happy.
[0] FRED also reports the instruction length, allowing one to deduce the trapping address.
tux3 14 hours ago [-]
I don't see how this happens in a C++ function, since breakpoint() is not noreturn you'd have to be doing something very strange for the next instruction to be outside the function. It's possible some debuggers will show the next line, and even then that seems like a debugger QoL issue that's fixable pretty mechanically. A soft breakpoint can come from CD 3 or CC, even if you don't get the instruction length from the CPU there aren't that many possibilities. I'm sure we don't need everyone to start inserting extra NOPs to get the desired behavior.
dwattttt 6 hours ago [-]
Agreed, and just to make it shorter and clearer; when you resume a debugger, it resumes at that next address. If it's outside a basic block, it's because in the absence of a debug break, it was about to go off the rails anyway, nothing to do with the break.
Joker_vD 14 hours ago [-]
...there is no bloody way debuggers don't just subtract 1 from the EIP on INT 3. Like... there is no way. Right?
Maxatar 13 hours ago [-]
If every single SIGTRAP was caused by an INT3 instruction, then this would work, but SIGTRAP can also be generated by single stepping where subtracting 1 would be incorrect.
GDB already compensates for breakpoints it inserts itself because it knows their locations, so it subtracts 1 as you suggest. It could also recognize embedded INT3 instructions but that requires distinguishing their traps from other causes of SIGTRAP which is much more complicated. So instead GDB generally leaves the instruction pointer unchanged for embedded INT3 instructions.
Here's a discussion of precisely this issue from the GDB developers:
An INT 3 isn't even always one byte; there's a one byte encoding, but I believe it's also legal to issue a two byte encoded INT N, where N is 3.
Agentlien 4 hours ago [-]
I've been working in C++ using VS for about 15 years and for as long as I've remembered my heuristic has been that if I get a breakpoint the offending instruction is on the line above what was reported.
dingaling911 14 hours ago [-]
Obscure knowledge. I wanted to see how well our LLM overlords would detect this circumstance but without proper prompting, it was happy with "just generate int3"
cowlevel 5 minutes ago [-]
The giant popup says "For C++ developers who give a damn" and then right under it is an AI slop blurb. Seems like it's more for people who don't give a damn. Now I'm thinking the article might be AI too.
singron 12 hours ago [-]
Pangram says the last 2/3rds are AI generated. I suspected when I got to this line:
> The separation of concerns is deliberate — breakpoint() and is_debugger_present() are orthogonal building blocks, and breakpoint_if_debugging() is the convenience composition.
It might be a false positive or just a few spots. Or maybe it's rage bait. I'm sorry if the author actually writes with this style.
Maxatar 11 hours ago [-]
It's pretty well established that this blog is LLM generated. The cpp subreddit has recently banned it, for example.
jchw 8 hours ago [-]
It's amazing and at this point, absolutely no surprise that HN has worse moderation of genAI than the cpp subreddit. The conflict of interest with AI has hit HN like 9/11.
locknitpicker 7 hours ago [-]
> It's amazing and at this point, absolutely no surprise that HN has worse moderation of genAI than the cpp subreddit.
I don't think this is a fair assessment. Submissions from specific sources are more frequent in niche forums, as this helps them stand out. So once a blog is found to be spamming, it's easier to target the blog and not individual submissions.
This is much harder to do on generalist forums such as HN.
jchw 6 hours ago [-]
Sure, sure, but they've already won by even having a policy against AI slop articles and posts, which, to my knowledge, HN seems steadfast in refusing to do so. After all, the public is fiercely divided into mostly one side in favor of banning said articles. HN is apparently just going to ride this out with only a policy banning LLM comments.
At this point, my only reason for still being around on here is because I simply don't know of any place that I find strictly better. Most of the popular alternatives to HN are annoying in ways that I find equally hard or even harder to tolerate.
koito17 7 hours ago [-]
I accepted I was reading LLM output by the time I got to
None are constexpr — debugging is a runtime concern.
I am not very experienced with C++, but runtime debug functions are one of the last things where I'd expect compile-time computations. Inlining? Sure. Doing anything else at compile-time? Not really.
The sentence feels like a remark about something a human reader is very unlikely to be thinking about.
fnord77 9 hours ago [-]
The chance that it is AI is much higher than the chance a human would use an em-dash (and not just an easily typeable "-" ) in a PR.
I bet that could be modeled with a markov chain
eklitzke 10 hours ago [-]
In the almost never cases I've had to do this I write `raise(SIGTRAP)`, portable to all Unixes.
Anybody know how MSVC plans to implement this, given their __forceinline still doesn't inline in debug mode?
pjmlp 3 hours ago [-]
They are finally delivering the missing pieces for C++23, who knows when they will do anything C++26 related.
1over137 9 hours ago [-]
I wish the C and C++ standards people would go through open source code out there and standardize all the platform-specific things like this case here.
pjmlp 3 hours ago [-]
The standards people are folks like yourself submitting papers, ideally alongside implementations.
Granted ISO processes are way more burecraty and secretive than discussing RFC pull requests on Github, however at the end of the day, the work is done by volunteers pushing their own agenda or the one from their employer.
Anyone can do it, if willing to deal with the process,
> Implementations are expected to optimize the code generated to be as minimal as possible for the platform. For example, on X86 it’s expected that this produces a single INT3 instruction. The goal in this expectation is to place the debugger as close as possible in the caller of breakpoint() to improve the debugging experience for users.
This is the wrong design on x86 at least with many debuggers. x86’s int3 is a trap and reports the address of the next instruction in the saved register state [0]. Most debuggers are not very clever and just use the saved address to generate the offending line of code and the call stack. But if the trap sequence is just int3, then the saved address could be outside the offending basic block or even outside the function entirely. gdb is certainly in the class of debuggers that get this wrong.
The easy workaround is to generate int3; nop for the breakpoint instead of just int3. The saved address will point to the nop and the debugger will be happy.
[0] FRED also reports the instruction length, allowing one to deduce the trapping address.
GDB already compensates for breakpoints it inserts itself because it knows their locations, so it subtracts 1 as you suggest. It could also recognize embedded INT3 instructions but that requires distinguishing their traps from other causes of SIGTRAP which is much more complicated. So instead GDB generally leaves the instruction pointer unchanged for embedded INT3 instructions.
Here's a discussion of precisely this issue from the GDB developers:
https://sourceware.org/pipermail/gdb/2009-February/034621.ht...
> The separation of concerns is deliberate — breakpoint() and is_debugger_present() are orthogonal building blocks, and breakpoint_if_debugging() is the convenience composition.
It might be a false positive or just a few spots. Or maybe it's rage bait. I'm sorry if the author actually writes with this style.
I don't think this is a fair assessment. Submissions from specific sources are more frequent in niche forums, as this helps them stand out. So once a blog is found to be spamming, it's easier to target the blog and not individual submissions.
This is much harder to do on generalist forums such as HN.
At this point, my only reason for still being around on here is because I simply don't know of any place that I find strictly better. Most of the popular alternatives to HN are annoying in ways that I find equally hard or even harder to tolerate.
The sentence feels like a remark about something a human reader is very unlikely to be thinking about.
I bet that could be modeled with a markov chain
Granted ISO processes are way more burecraty and secretive than discussing RFC pull requests on Github, however at the end of the day, the work is done by volunteers pushing their own agenda or the one from their employer.
Anyone can do it, if willing to deal with the process,
https://isocpp.org/std/meetings-and-participation
https://www.open-std.org/jtc1/sc22/wg14/www/contributing.htm...
The C and C++ standards people are you and me. The proposal to standardize debugging calls comes from a long time contributor to Boost.