edb-debugger
edb-debugger copied to clipboard
Make long disassembly lines easier to view completely
Currently, if a disassembly line appears too long, it's not possible to view it completely, unless you do some tricks like moving rIP to it and seeing operand address in analysis view. See this example screenshot:
There exists a technique I think is quite useful, like in the following animation of a Windows XP's stock dialog:
It'd be good if EDB could apply it to its Disassembly View, for all three currently existing columns — address, opcode and disassembly. When the text is too long to be seen on the whole remaining width to the right of the column, the tooltip could extend to multiple lines.
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
This is a cool idea, I'll look into how to implement it well.
I'll take this one on and try to complete it in the next 2 weeks. I don't think it's complex but my time might be minimal.
I'm working on this. I have a pixel perfect solution but the problem is that it is forced to disappear too early and I'm troubleshooting why. I'm using the QToolTip's advanced parameters to assign a rectangle that should allow the tip to stick around and settign a longer stay-time, but something is amiss. Different platforms have a hard coded offset in QT to the right and down from the mouse cursor and I use a correction adjustment to counter this offset
Just have to fix the "stick around" problem and we'll be good.
--- a/src/widgets/QDisassemblyView.cpp
+++ b/src/widgets/QDisassemblyView.cpp
@@ -213,6 +213,7 @@ QDisassemblyView::QDisassemblyView(QWidget * parent) : QAbstractScrollArea(paren
setShowAddressSeparator(true);
setFont(QFont("Monospace", 8));
+ QToolTip::setFont(QFont("Monospace", 8));
setMouseTracking(true);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
@@ -1194,8 +1195,19 @@ bool QDisassemblyView::event(QEvent *event) {
const edb::Instruction inst(buf, buf + buf_size, address);
const QString byte_buffer = format_instruction_bytes(inst);
+ //Construct correction for QT's native offset
+ QPoint ToolTipNativecCorrection(2,16);
+
+ //Construct anchor so event directly overlays line of code
+ QPoint anchor( mapToGlobal( QPoint{line1(), ( helpEvent->y() / line_height() ) * line_height()} ) );
+
+ //Attempt to construct the rectangle so that the tooltip will stay while the mouse is over the line of code
+ QRect ttipStayRect( line1(), ( helpEvent->y() / line_height() ) * line_height(), line_height(), line2()-line1());
+
+
if((line1() + byte_buffer.size() * font_width_) > line2()) {
- QToolTip::showText(helpEvent->globalPos(), byte_buffer);
+ QToolTip::showText(anchor-ToolTipNativecCorrection, byte_buffer, viewport(), viewport()->rect(), 10000);
+ //QToolTip::showText(helpEvent->globalPos(), byte_buffer, viewport(), QRect(), 10000);
show = true;
}
}
I've tried multiple variations so the code that I quoted is not the original attempt....but I can't seem to get it to stick around no matter what.
I originally used this but realised I need the viewport widget. Then I tried all manner of rectangles...the tooltip doesn't seem to respond to the mouse being in the rectangle. If you move the mouse away..it just disappears.
The key part is the anchor-ToolTipNativeCorrection to place it directly over the current line.
I'm just providing code in case someone else can figure out the problem with sticking around.
FYI, on my system I had to adjust the correction from your (2,16)
to (1,17)
to get pixel perfection (with KDE4 Oxygen style). Also, on Qt4 there's no overload of QTooltip::showText
taking time as parameter (and EDB currently tries to maintain compatibility with Qt4).
As for the tooltip disappearing, its seems it's the way it reacts to mouse cursor being above it. It might need to be reimplemented/subclassed to handle this properly.
I wonder if the offset is somewhere in a QStyle object that were can interrogate to get the correct value regardless of style Qt is using.
Yeah, maybe something like QStyle::pixelMetric()
.
For some reason, the QTipLabel
(the private Qt's QWidget
representing the tooltip) gets QEvent::Leave
as soon as it shows up. Then its event filter just calls hideTip
. I'm not sure why the event appears in the first place.
Here's a version which does work for me using a hack to avoid closing due to Leave event: 10110111@6afe4dd
.
The font is now also chosen correctly, unlike the original version, where non-default font didn't work. The only thing remaining here is correctly finding the offset to move the tooltip. It appears different even with different fonts, not only with different QStyle
s.
In fact, the positioning of tooltip seems to be quite tricky to handle correctly in general. See QTipLabel::placeTip
source. We may want to manually move it after it shows up, although this still requires us to know the rectangle the text is in relative to the tooltip widget.
OK, I seem to have succeeded in pixel-perfect placement across a variety of different themes and font sizes. Here's the patch. Comments are welcome. Ideally this should go into a separate function, accessible to tooltipize all the columns of disassembly view, including address and disassembly (and comments?), not only instruction bytes. Current version of the patch is just a proof of concept.
This is wonderful. I indeed was using QT5, but it seems you've sussed out all of the pertinent details. I'll give it a go in the next couple days and leave my feedback. If it works, I'll functionize it. :)