edb-debugger icon indicating copy to clipboard operation
edb-debugger copied to clipboard

Make long disassembly lines easier to view completely

Open 10110111 opened this issue 8 years ago • 12 comments

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: Example screenshot of the problem There exists a technique I think is quite useful, like in the following animation of a Windows XP's stock dialog: Principle of solution 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.

10110111 avatar Jan 17 '16 13:01 10110111

This is a cool idea, I'll look into how to implement it well.

eteran avatar Jan 17 '16 18:01 eteran

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.

RabidCicada avatar May 03 '16 16:05 RabidCicada

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;
                                        }
                                }

RabidCicada avatar May 10 '16 13:05 RabidCicada

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.

RabidCicada avatar May 10 '16 13:05 RabidCicada

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.

10110111 avatar May 10 '16 16:05 10110111

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.

eteran avatar May 10 '16 18:05 eteran

Yeah, maybe something like QStyle::pixelMetric().

10110111 avatar May 10 '16 19:05 10110111

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.

10110111 avatar May 10 '16 20:05 10110111

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 QStyles.

10110111 avatar May 11 '16 06:05 10110111

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.

10110111 avatar May 11 '16 06:05 10110111

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.

10110111 avatar May 13 '16 06:05 10110111

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. :)

RabidCicada avatar May 31 '16 21:05 RabidCicada