Loading ...
Sorry, an error occurred while loading the content.

Re: [soaplite] SOAP::Lite interaction w/ Exception::Class results in Perl seg fault

Expand Messages
  • Peter Chen
    ... One possibility is a pragma like approach. For example, one can add a parameter in the import function, so one may: use SOAP::Lite gen_id = safe ;
    Message 1 of 4 , Jan 8, 2003
    • 0 Attachment
      On Wed, 2003-01-08 at 14:26, Paul Kulchenko wrote:
      > You're right. gen_id doesn't handle stringified objects well.
      ...
      > sub gen_id { overload::StrVal($_[1]) =~ /\((0x\w+)\)/o; $1 }
      >
      > Performance is the reason why sprintf %U is used. The version that
      > uses overload::StrVal is significantly slower and I hasn't been able
      > to find a combination that performs well.
      >
      > It's easy to override gen_id in your version of serializer, but I'm
      > not sure what's the best way to fix it once and for all. Thoughts?

      One possibility is a "pragma" like approach. For example, one can add a
      parameter in the import function, so one may:

      use SOAP::Lite 'gen_id' => 'safe';

      Different versions of gen_id() can be loaded based on its setting.

      I frequently see this for modules that have separate development and
      production mode. This is not a complete solution, but it gives people
      and option.

      > P.S. One related thought. I've been thinking about adding handling
      > for Exception::Class (SOAP::Server::handle, 2221) or, perhaps,
      > providing on_fault method on a server side, so that you can handle
      > fault and return the result you need. It hasn't been implemented yet
      > thought.

      I like this idea, even though I suspect this will take more work than my
      proposal above. Then again, they are not mutually exclusive. If there
      is such a callback, I may custom tailor how I serialize Exception::Class
      objects. For example, Exception::Class allows one to define custom
      fields, in on_fault method, I may then check the class of the exception
      object, and provide different serialization for different exception
      classes.

      Pete
    • dtikhonov
      Let s revisit this thread. I did my own investigation of the problem and realized that the problem is not stringification, but numeric conversion overloading
      Message 2 of 4 , Jan 25, 2006
      • 0 Attachment
        Let's revisit this thread. I did my own investigation of the problem
        and realized that the problem is not stringification, but numeric
        conversion overloading done in Error.pm. Here's my analysis from
        perlmonks.org[1]:

        ---------------------------------------------
        I have a server written in Perl that does some tasks that clients ask
        it to. Requests and responses are passed using soap, namely
        SOAP::Lite. Responses can be successful or unsuccessful. The latter
        are of two types: error codes plus honest-to-God exceptions (well, as
        close as Perl comes to them, anyway) of type Error or
        Exception::Class. The problem occurs when SOAP::Serializer tries to
        serialize objects of type Error. Error.pm has the following code
        (shortened for our purposes):

        use overload ("0+" => 'value');
        sub value {
        my $self = shift;
        exists $self->{'-value'} ? $self->{'-value'} : undef;
        }

        Note that this subroutine may return undef. Now, SOAP::Serializer
        calls subroutine gen_id on references, which for normal objects is
        just the value of memory address:

        sub gen_id { sprintf "%U", $_[1] }

        Now, the problem is that when objects of type Error do not have a
        value (returns undef), this produces a segfault in perl 5.6.1. This
        problem can be demonstrated with the following short script:

        package My;

        use overload ('0+' => 'num_conv');
        sub new {
        my $self = shift;
        bless {}, ref($self) || $self;
        }
        sub num_conv { undef }

        package main;
        my $var = My->new;
        print int($var);
        ---------------------------------------------

        We can see that gen_id should try to detect whether object has numeric
        conversion overloaded and if it does, use a different scheme to get
        the ID (such as Scalar::Util::refaddr, also suggested in the perlmonks
        thread).

        Thoughts?

        - Dmitri.

        1. http://www.perlmonks.org/?node_id=525293
      Your message has been successfully submitted and would be delivered to recipients shortly.