Repository navigation
Support instruction-level debugging in pdb #103049
Description
Activity
- addedtype-featureA feature request or enhancementA feature request or enhancement
on Mar 27, 2023 I linked a prototype for the instruction display. Please let me know if we want to proceed on this feature. I can either do two PRs(I would assume
siis going to be rather complicated) or do a big one.We don't want a
discommand as it's easy for users to add an alias if they so choose. Using.pdbrcthey can define aliases that are always available.As for working with opcodes, that's an interesting idea! But do we need a separate assembly mode? It feels to me like it would be more flexible to add new commands for this, like
lo|listopcodesandllo|longlistopcodes. What do you think?I was actually torn between the two ideas - whether to overload the existing command with a state flipper, or to add two extra commands. There are two reasons I'm leaning slightly toward the state solution:
- In my imagine, users either need to debug on instruction level or not. Keeping two very similar functions in the same command seems a bit clearer. It can inherit all the features/options from
landll. - With the state, we can do some other tricks like display the instruction after the breakpoint(step) in assembly mode.
I can go along with the extra commands as well, the debugger I was using for C in my prev company uses more like a state switch solution. We can only display the current instruction when the user uses
si(or in the future other instruction-level commands).Actually there's another possibility - we overload everything. In assembly mode,
stepmeansstepinstruction. I believe this is how windbgx works. If the users switched to "assembly mode", clicking "step" actually steps a single instruction. That's also one possible solution.The reason I brought up a new command for
disis that there are equivalents in gcc(and probably other debuggers). True the user can achieve that with.pdbrcwithalias, but that's true for a lot of other commands(whatis,interact,retval...). I think the ultimate decision falls on - will this introduce more trouble for the users don't use it, or will it benefits more for the users who do.Also I guess there are a couple of names for the
instruction.disassemblyis one andopcodeyou used. I always thinkopcodeis referring to the actual instruction type likeLOAD_GLOBALorCACHE, whereasinstructionis the full package with arguments, line number, positions and stuff. That's also how it's used indisdocs if I understand correctly.On the side note, now that I think about it,
siandniare two different commands and we need to separate them.- In my imagine, users either need to debug on instruction level or not. Keeping two very similar functions in the same command seems a bit clearer. It can inherit all the features/options from
I am excited about this proposal. Indeed, there are plenty of options for how this could be implemented. I would like to know your thoughts on how LLDB handles disassembly.
LLDB has separate commands for source and instruction level stepping:
nfor source level single stepnifor instruction level single step
Additionally, LLDB provides settings to control whether to display disassembly when stopped. I took a couple of screenshots for demonstration.
By default, LLDB only shows source code when stopped, even with instruction level stepping:
Although it does not display disassembly, it marks the corresponding piece of code that is being executed.
By setting
settings set stop-disassembly-display always, you can examine the source code and the assembly code at the same time:Do you think pdb could provide a similar user experience? And how beneficial would such behaviour be for Python programmers?
pdbcurrently does not have asettingscommand to handle all potential settings (maybe for the nextpdbwe should consider that).assemwould be the first state command if introduced.I guess having
assemstate determine whether to step inst or line is not that great an idea on command line tools. It's nice on GUI where the button overloading has more benifits. On command line tools, I guess users would like more distinct commands.Personally, I'd like my debugger to show some difference when I do
ni. Just a note here that we can do specific code now withposition. I still think displaying the current instruction afterniwould be a better user experience.pdbonly list a single source line, compared tolldbwhich has more context. So adding another instruction line would be cheaper(screen space wise) thanlldb. Also, it we do not have state, we won't have a choice - so it's either with or without. I'd lean forward to with.As for the benefits, I'm not sure. I would guess most of the Python users debug their program with
print(). Even among the people who are usingpdb, most of them probably are not familiar with bytecodes. However, the number of users of Python is so large that if a small portion of a small portion is a significant number. At least for me, I often want to see the actual compiled bytecode of the function to see what's really going on there. (Thus the thought ofdis, which would be super convenient).I'm totally fine with
liandlliinstead ofassem. Just want to hear more from the actual users.Dear nosy:
I've finished a draft for the implementation. I decided to go no-state. Separate commands for all instruction-related stuff. So,
li,lli,siandni. Also when you dosiandni, the current instruction will be displayed in the prompt.Anyone has suggestions/questions on this? Once the implementation is reviewed and confirmed, I can work on the tests and docs.
Reacted by Łukasz LangaOverall, this approach looks good to me! I agree that it better suits CLI than having a separate assembly mode. I also like that
niandsishow me both the current source line and the current instruction.One more thing to consider is the terminal width. Disassembly output can be wide, at least because of the full file paths:
(Pdb) li 1 -> def foo(a, b): --> 2 LOAD_CONST 0 (<code object foo at 0x101651210, file "/very/long/full/path/to/foo.py", line 1>)However, I do not have a particular idea of how to approach that properly.
One more thing to consider is the terminal width. Disassembly output can be wide, at least because of the full file paths:
Unfortunately, this piece is using the internal function of
disdirectly, which will provide a familiar experience todisusers (assuming most of the people interested in instructions are usingdis).dishas similar issues and I guess there's no perfect way to deal with it.Hi all, the feature, test and docs are all finished and ready for review now.
This is very technically cool, but I can't think of any use cases for end users and it's a lot of code. (Am I just not creative enough?)
I can, however, imagine that core devs working on the Python bytecode compiler will get benefit from it. Maybe we should get buy in from some potential users before complicating Bdb?
This is very technically cool, but I can't think of any use cases for end users and it's a lot of code. (Am I just not creative enough?)
I can, however, imagine that core devs working on the Python bytecode compiler will get benefit from it. Maybe we should get buy in from some potential users before complicating Bdb?
Python has
f_trace_opcodes, so the ability to trace and debug opcode (instruction) is natural. The end user of Python is a large base, I for example, often need the capability to debug on instruction level. It's also very helpful to debug CPython itself.All I'm saying is, there are different needs for different developers - for a lot of developers, they do not even use debuggers,. Having a working solution for debugging instructions does not make pdb worse. And yes, there are more code in bdb, but most of them are on isolated paths that are very specific to instruction tracing. It does not impact the current bdb responsibilities.
For use cases, there is a very common pattern in Python - one-liners. Often they consist of multiple expressions. As of now, pdb can only execute it as a full line, and the debuggability within the line is horrible. Having an instruction-level debugging in pdb would solve that.
However, with the new PEP 669, this work is blocked by the implementation of #103615 , which I'm also responsible for. So this feature will only be visited later.
- addedstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
on Nov 29, 2023


Feature or enhancement
Support instruction-level debugging in pdb
liandllito display instructions with source codesiandnicommandPitch
pdbcould provide a better debugging experience by supporting instruction level debugging. We already have most of the utilities but we need to put them together.The new commands will be introduced:
li(listinst),lli(longlistinst),si(stepinst)andni(nextinst)(Another candidate would bedis, which is short forimport dis; dis.dis()).liandlliwill list source file with the instructions.siwill step one instruction ahead andniwill stay in this frame. We haveopcodeevent to support this.Previous discussion
Did not find any.
Linked PRs