python's frame comparison support just calls frame_id_eq, but that can return true for the "same" frame in different inferiors. repro: bash$ gdb hello (gdb) start (gdb) py f1 = gdb.selected_frame () (gdb) add-infer -exec hello (gdb) infer 2 (gdb) start (gdb) py f2 = gdb.selected_frame () (gdb) py print f1 == f2 True
Another issue: To what extent does gdb.Frame.older,newer assume the user doesn't change the current inferior?
> python's frame comparison support just calls frame_id_eq, but that can return > true for the "same" frame in different inferiors. Or different threads of the same inferior, even. Usually that won't happen because each thread will have its own stack frame, but it can happen. E.g., if previous thread exits, and new thread reuses stack. Or, if signal/exception handler runs on its own stack, no matter which thread was current, the same frame can be seen from both threads. In a way, returning true for f1 == f2 isn't that much of a stretch. They are two different instantiations of the same frame. You'd want that to be true if e.g., you were debugging a multi-process program (multiple forks), and wanted to do something similar to gdb's builtin local watchpoint handling (stop only on frame XX). I think it should be up to the higher level code to make sure it makes sense to compare the frames.
(In reply to Pedro Alves from comment #2) > > python's frame comparison support just calls frame_id_eq, but that can return > true for the "same" frame in different inferiors. > > Or different threads of the same inferior, even. I know. > Usually that won't happen > because each thread will have its own stack frame, but it can happen. E.g., > if previous thread exits, and new thread reuses stack. Or, if > signal/exception handler runs on its own stack, no matter which thread was > current, the same frame can be seen from both threads. Cases I entertained myself. > In a way, returning true for f1 == f2 isn't that much of a stretch. They > are two different instantiations of the same frame. You'd want that to be > true if e.g., you were debugging a multi-process program (multiple forks), > and wanted to do something similar to gdb's builtin local watchpoint > handling (stop only on frame XX). I think it should be up to the higher > level code to make sure it makes sense to compare the frames. I'm not prepared to go that far, but whatever.
(In reply to Pedro Alves from comment #2) > In a way, returning true for f1 == f2 isn't that much of a stretch. They > are two different instantiations of the same frame. You'd want that to be > true if e.g., you were debugging a multi-process program (multiple forks), > and wanted to do something similar to gdb's builtin local watchpoint > handling (stop only on frame XX). I think it should be up to the higher > level code to make sure it makes sense to compare the frames. I tend to agree here -- and I really disagree with the way the subject of this PR, as written -- but it's worth considering the ramifications of bug #16186. If we had per-thread unwinding API then the frame would have to carry a reference to the thread along with it, or else there'd be no way to unwind without extra context.
Filed for reference sake. The subject of this pr was written to recognize how frames are used today, while at the same time recognizing there are problems with it. It seems to me that, for example, if I get the newest frame in the current inferior, change inferiors, and then try to take the older frame of that frame, it can "work" in cases where an error would be preferable. Ideally, frames would be per-thread. Doesn't seem that controversial. Getting there on the other hand isn't something I was prepared to believe would be a slam dunk. Hence the compromise in the phrasing of the PR.
If Python should not use frame_id_eq to determine equality what method of frame equality should it use?