Suspicious QWidget Initialization Behaviour

View: New views
5 Messages — Rating Filter:   Alert me  

Suspicious QWidget Initialization Behaviour

by Jonathan Yu :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Chris:

I'm not sure where this is happening, or perhaps if it's just a usage
error. I'm creating a new object of a class that inherits from
Qt::Widget. I've noticed if I do [the equivalent of]:
Qt::Widget->new();

Then I get a core dump with the following backtrace:

#0  QWidget::sizePolicy (this=0x0) at kernel/qwidget.cpp:8925
8925 kernel/qwidget.cpp: No such file or directory.
        in kernel/qwidget.cpp
(gdb) bt full
#0  QWidget::sizePolicy (this=0x0) at kernel/qwidget.cpp:8925
No locals.
#1  0xb7a6a938 in xcall_QWidget (xi=<value optimized out>, obj=0x0,
    args=0x9bb7d08) at /home/jon/kdebindings/build/smoke/qt/x_20.cpp:4820
No locals.
#2  0xb7bd5153 in PerlQt::MethodCall::callMethod (this=0xbf9b1860)
    at src/marshall_types.h:132
        method = (Smoke::Method *) 0xb7b2feac
        fn = (void (*)(short int, void *,
    Smoke::StackItem *)) 0xb7a69c40 <xcall_QWidget(short, void*,
Smoke::StackItem*)>
        ptr = (void *) 0x0
        callreturn = {<PerlQt::MethodReturnValueBase> = {<Marshall> = {
      _vptr.Marshall = 0xbf9b1668}, _smoke = 0x80abc27, _methodIndex = -31492,
    _stack = 0x8f98548, _retval = 0xb7f32ff4}, <No data fields>}
#3  0xb7bd1f38 in PerlQt::MethodCallBase::next (this=0xbf9b1860)
    at src/marshall_types.cpp:387
        oldcur = -1
#4  0xb7bc803c in XS_AUTOLOAD (my_perl=0x8f98008, cv=0x99da9d8)
    at src/util.cpp:1223
        classId = 5364
        methodId = <value optimized out>
        rcid = <value optimized out>

It looks like a void pointer (ptr) is being passed to the sizePolicy,
and I'm not sure if this is a Qt bug or a PerlQt bug. Either way it's
due to improper checking of parameters -- ie maybe trying to
dereference the null pointer.

Thanks in advance for any help you can offer here.

On an unrelated note, I've discovered while debugging code that
"Carp::Always" is a very useful module. It makes calls to "die" dump a
full backtrace, meaning the issues with ambiguous methods croak'ing
from XS will dump a full backtrace. It's tremendously useful for
debugging.

Cheers,

Jonathan
_______________________________________________
Kde-perl mailing list
Kde-perl@...
https://mail.kde.org/mailman/listinfo/kde-perl

Re: Suspicious QWidget Initialization Behaviour

by Gary L. Greene, Jr.-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Monday 10 August 2009 8:10:11 pm Jonathan Yu wrote:

> Hi Chris:
>
> I'm not sure where this is happening, or perhaps if it's just a usage
> error. I'm creating a new object of a class that inherits from
> Qt::Widget. I've noticed if I do [the equivalent of]:
> Qt::Widget->new();
>
> Then I get a core dump with the following backtrace:
>
> #0  QWidget::sizePolicy (this=0x0) at kernel/qwidget.cpp:8925
> 8925 kernel/qwidget.cpp: No such file or directory.
> in kernel/qwidget.cpp
> (gdb) bt full
> #0  QWidget::sizePolicy (this=0x0) at kernel/qwidget.cpp:8925
> No locals.
> #1  0xb7a6a938 in xcall_QWidget (xi=<value optimized out>, obj=0x0,
>     args=0x9bb7d08) at /home/jon/kdebindings/build/smoke/qt/x_20.cpp:4820
> No locals.
> #2  0xb7bd5153 in PerlQt::MethodCall::callMethod (this=0xbf9b1860)
>     at src/marshall_types.h:132
> method = (Smoke::Method *) 0xb7b2feac
> fn = (void (*)(short int, void *,
>     Smoke::StackItem *)) 0xb7a69c40 <xcall_QWidget(short, void*,
> Smoke::StackItem*)>
> ptr = (void *) 0x0
> callreturn = {<PerlQt::MethodReturnValueBase> = {<Marshall> = {
>       _vptr.Marshall = 0xbf9b1668}, _smoke = 0x80abc27, _methodIndex =
>  -31492, _stack = 0x8f98548, _retval = 0xb7f32ff4}, <No data fields>}
> #3  0xb7bd1f38 in PerlQt::MethodCallBase::next (this=0xbf9b1860)
>     at src/marshall_types.cpp:387
> oldcur = -1
> #4  0xb7bc803c in XS_AUTOLOAD (my_perl=0x8f98008, cv=0x99da9d8)
>     at src/util.cpp:1223
> classId = 5364
> methodId = <value optimized out>
> rcid = <value optimized out>
>
> It looks like a void pointer (ptr) is being passed to the sizePolicy,
> and I'm not sure if this is a Qt bug or a PerlQt bug. Either way it's
> due to improper checking of parameters -- ie maybe trying to
> dereference the null pointer.
>
> Thanks in advance for any help you can offer here.
>
> On an unrelated note, I've discovered while debugging code that
> "Carp::Always" is a very useful module. It makes calls to "die" dump a
> full backtrace, meaning the issues with ambiguous methods croak'ing
> from XS will dump a full backtrace. It's tremendously useful for
> debugging.
>
> Cheers,
>
> Jonathan
> _______________________________________________
> Kde-perl mailing list
> Kde-perl@...
> https://mail.kde.org/mailman/listinfo/kde-perl
>

Dunno if this still works in PerlQt4, did in 3....
Another useful aspect is doing the following:

use Qt::debug qw| CHANNEL |;

Where CHANNEL is one of:

ambiguous, verbose, calls, autoload, gc, virtual, all

These were all described in the POD for PerlQt3. As I said, I don't know if
they still work in PerlQt4.
_______________________________________________
Kde-perl mailing list
Kde-perl@...
https://mail.kde.org/mailman/listinfo/kde-perl

Re: Suspicious QWidget Initialization Behaviour

by Chris Burel :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, Aug 10, 2009 at 8:47 PM, Gary Greene<greeneg@...> wrote:

> On Monday 10 August 2009 8:10:11 pm Jonathan Yu wrote:
>> Hi Chris:
>>
>> I'm not sure where this is happening, or perhaps if it's just a usage
>> error. I'm creating a new object of a class that inherits from
>> Qt::Widget. I've noticed if I do [the equivalent of]:
>> Qt::Widget->new();
>>
>> Then I get a core dump with the following backtrace:
>>
>> #0  QWidget::sizePolicy (this=0x0) at kernel/qwidget.cpp:8925
>> 8925  kernel/qwidget.cpp: No such file or directory.
>>       in kernel/qwidget.cpp

I'm not sure exactly where your code is failing, so I'll outline a
couple things that have to happen for subclasses to work.

You can't (currently) call "MySubclass->new( @args )".  It's just
"MySubclass( @args)".  This will be routed to MySubclass::NEW(
$classname, @args);
Tell Qt what you're subclassing from by placing "use Qt::isa qw(
ParentClass )" in your subclass's module.
You have to implement a NEW() method in your subclass.  The NEW()
method must call $class->SUPER::NEW();
Every method call made from the subclass should be made on the "this"
object.  This is the main deviation from PerlQt3.

For example:
#!/usr/bin/perl

package Foo;

use strict;
use warnings;
use Qt;
use Qt::isa qw( Qt::Widget );

sub NEW {
    my ( $class, $parent ) = @_;
    $class->SUPER::NEW( $parent );  # not Qt::Widget->new( $parent )
    this->resize( 500, 500 );    # not just resize( 500, 500 );
}

package main;

use strict;
use warnings;
use Qt;
use Foo;

sub main {
    my $app = Qt::Application( \@ARGV );
    my $widget = Foo( undef );    # not Foo->new
    $widget->show();
    return $app->exec();
}

main();

> Dunno if this still works in PerlQt4, did in 3....
> Another useful aspect is doing the following:
>
> use Qt::debug qw| CHANNEL |;
>
> Where CHANNEL is one of:
>
> ambiguous, verbose, calls, autoload, gc, virtual, all
>
These are still present in PerlQt4, but have to be enabled at compile
time.  Maybe I'm mistaken, but I figured that stuff was only useful to
people developing the bindings, and not to normal users of the
bindings.  So I thought it was silly to have a bunch of "if( debug )"
tests when running normal code.
If you want to enable those debug messages, specify -DDEBUG while compiling.
On that note, is there a better/more standard define to use for those
sort of debugging messages?

--Chris
_______________________________________________
Kde-perl mailing list
Kde-perl@...
https://mail.kde.org/mailman/listinfo/kde-perl

Re: Suspicious QWidget Initialization Behaviour

by Gary L. Greene, Jr.-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Monday 10 August 2009 10:36:52 pm Chris Burel wrote:

> > Dunno if this still works in PerlQt4, did in 3....
> > Another useful aspect is doing the following:
> >
> > use Qt::debug qw| CHANNEL |;
> >
> > Where CHANNEL is one of:
> >
> > ambiguous, verbose, calls, autoload, gc, virtual, all
>
> These are still present in PerlQt4, but have to be enabled at compile
> time.  Maybe I'm mistaken, but I figured that stuff was only useful to
> people developing the bindings, and not to normal users of the
> bindings.  So I thought it was silly to have a bunch of "if( debug )"
> tests when running normal code.
> If you want to enable those debug messages, specify -DDEBUG while
>  compiling. On that note, is there a better/more standard define to use for
>  those sort of debugging messages?

I found this VERY useful when dealing with code paths not working the way I
wanted. Admittedly this was because the PerlKDE3 code is missing a number of
important classes (KXMLGuiFactory for one....), but this was very handy in
being able to access the call stack during development of an app.

With regard to what would be "better" would imo, to change that from having to
import a whole new module to activate it to changing it to be a configuration
option to the main module as it's being used:

use Qt qw(debug: CHANNEL);

This way Qt::debug could be redone so it can be used to register new debug
CHANNELS for the app. This also fits better with a number of modules out there
that do much the same re the use of the use parameter for loading modules.

Just my $0.02

>
> --Chris
> _______________________________________________
> Kde-perl mailing list
> Kde-perl@...
> https://mail.kde.org/mailman/listinfo/kde-perl
>

_______________________________________________
Kde-perl mailing list
Kde-perl@...
https://mail.kde.org/mailman/listinfo/kde-perl

Re: Suspicious QWidget Initialization Behaviour

by Jonathan Yu :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Chris:

On Tue, Aug 11, 2009 at 1:36 AM, Chris Burel<chrisburel@...> wrote:
> On Mon, Aug 10, 2009 at 8:47 PM, Gary Greene<greeneg@...> wrote:
>> On Monday 10 August 2009 8:10:11 pm Jonathan Yu wrote:
>>> Hi Chris:
>>>
>>> I'm not sure where this is happening, or perhaps if it's just a usage
>>> error. I'm creating a new object of a class that inherits from
>>> Qt::Widget. I've noticed if I do [the equivalent of]:
>>> Qt::Widget->new();
Note I wasn't actually doing that code. The actual code is a bit
hairy, but it's in the SVN repository for perlqt4. Notably it's this
code in Kde.pm (http://code.google.com/p/perlqt4/source/browse/trunk/Debconf/Element/Kde.pm)

This is the code I'm using in the constructor, which I believe is what
causes the core dump (since changing it around I get the Unknown
Method Combination Error):

sub NEW {
        shift->SUPER::NEW (@_[0..2]);
        this->{mytop} = undef;
}

Though in my working copy I changed that to:
sub NEW {
        shift->SUPER::NEW (shift);
        this->{mytop} = undef;
}

(This is because the old Qt::Widget constructor for Qt3 required more
parameters than Qt4, so I've updated it to match Qt4's.)

I even tried using:

shift->SUPER::NEW(shift, 0)

Where the first shift would be $class and the second shift would be
the $parent. The third parameter is just f, which is set to zero by
default.

I'm not sure if it's actually a bug somewhere, but still, having a
core dump is probably a Bad Thing if it can be avoided (using
parameter checking/exceptions).

>>>
>>> Then I get a core dump with the following backtrace:
>>>
>>> #0  QWidget::sizePolicy (this=0x0) at kernel/qwidget.cpp:8925
>>> 8925  kernel/qwidget.cpp: No such file or directory.
>>>       in kernel/qwidget.cpp
>
> I'm not sure exactly where your code is failing, so I'll outline a
> couple things that have to happen for subclasses to work.
>
> You can't (currently) call "MySubclass->new( @args )".  It's just
> "MySubclass( @args)".  This will be routed to MySubclass::NEW(
> $classname, @args);
> Tell Qt what you're subclassing from by placing "use Qt::isa qw(
> ParentClass )" in your subclass's module.
> You have to implement a NEW() method in your subclass.  The NEW()
> method must call $class->SUPER::NEW();
> Every method call made from the subclass should be made on the "this"
> object.  This is the main deviation from PerlQt3.
>
> For example:
> #!/usr/bin/perl
>
> package Foo;
>
> use strict;
> use warnings;
> use Qt;
> use Qt::isa qw( Qt::Widget );
>
> sub NEW {
>    my ( $class, $parent ) = @_;
>    $class->SUPER::NEW( $parent );  # not Qt::Widget->new( $parent )
>    this->resize( 500, 500 );    # not just resize( 500, 500 );
> }
>
> package main;
>
> use strict;
> use warnings;
> use Qt;
> use Foo;
>
> sub main {
>    my $app = Qt::Application( \@ARGV );
>    my $widget = Foo( undef );    # not Foo->new
>    $widget->show();
>    return $app->exec();
> }
>
> main();
>
>> Dunno if this still works in PerlQt4, did in 3....
>> Another useful aspect is doing the following:
>>
>> use Qt::debug qw| CHANNEL |;
>>
>> Where CHANNEL is one of:
>>
>> ambiguous, verbose, calls, autoload, gc, virtual, all
>>
> These are still present in PerlQt4, but have to be enabled at compile
> time.  Maybe I'm mistaken, but I figured that stuff was only useful to
> people developing the bindings, and not to normal users of the
> bindings.  So I thought it was silly to have a bunch of "if( debug )"
> tests when running normal code.
> If you want to enable those debug messages, specify -DDEBUG while compiling.
> On that note, is there a better/more standard define to use for those
> sort of debugging messages?
>
> --Chris
>
_______________________________________________
Kde-perl mailing list
Kde-perl@...
https://mail.kde.org/mailman/listinfo/kde-perl