Again, I’m not familiar with debug events. A more knowledgeable person might chime in to comment, or you may want to open an issue on the compiler codebase to get more answers. (Please make sure to include a clear description of what you are trying to do and what you expect.) Below is my best-effort attempt at saying a bit more.
One thing that would help is understand what you are trying to do. I suspect it is “walk up the call stack using the debugger protocol, and expect to see all things that logically look like function calls to the user”. It may be that “yeah this is actually not a function call, so it is not a frame on the call stack and the debugger will skip it” is the best current answer, I am not sure. Ideally there should be a way to keep information on “virtual” calls that have been inlined, but I don’t know that such a mechanism exist today. (At first I thought that this part of primitive translation was doing that, but as I read more stuff I understand that this looks more related to the ability to put breakpoints after the primitive returned).
Note that there are other primitives that result in code generation instead of a function call,
Printexc.raise_with_backtrace for example.
Finally: while investigating your issue I noticed that there is a discrepancy between native and bytecode backtraces involving
Lazy.force in 4.12 development version (there was a native-code improvement that does not affect the bytecode, it seems), I asked about this in https://github.com/ocaml/ocaml/pull/9469#issuecomment-757495542.