-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
segfault using ParamValues from $sth #447
Comments
Only a single test references If you confirm that we intend to support this attribute, I might try to add some tests, perhaps in some of |
Did you mean to include the
I'm not sure if these have to start at 1. I'm not even sure if these have to be integers. Some other drivers (e.g. DBD::Pg) support named parameters, not sure how those are handled. However I'm all for making DBD::mysql follow what DBI::Log does where possible. Do you want to create a PR for that? |
I did not include my However, actually solving the problem is probably beyond what I can do. I have no experience as an XS developer, and no time currently to become one. |
I think a new file based on the GitHub issue number like
That's fine. Thanks for the detailed report. |
@myrrhlin Please check #449 and let me know what you think. I used this to test: #!/bin/perl
use v5.40;
use Data::Dumper;
use DBI;
my $dbh = DBI->connect('DBI:mysql:database=test', 'root', '');
say "query: SELECT ? (arg: 1)";
my $sth = $dbh->prepare('SELECT ?');
say "before execute:\n" . Dumper($sth->{ParamValues});
$sth->execute(1);
say "after execute:\n" . Dumper($sth->{ParamValues});
while (my @row = $sth->fetchrow_array()) {
say "result: " . $row[0];
}
$sth->finish;
say "\nquery: SELECT ?, ? (arg: 1,2)";
$sth = $dbh->prepare('SELECT ?, ?');
say "before execute:\n" . Dumper($sth->{ParamValues});
$sth->execute(1, 2);
say "after execute:\n" . Dumper($sth->{ParamValues});
while (my @row = $sth->fetchrow_array()) {
say "result: " . $row[0] . "," . $row[1];
}
$sth->finish; output:
This will need a testcase before it is merged. |
And this code: #!/bin/perl
use v5.40;
use Data::Dumper;
use DBI;
my $dbh = DBI->connect('DBI:mysql:database=test', 'root', '', {
ShowErrorStatement => 1,
});
my $sth = $dbh->prepare('select now(?)');
$sth->bind_param(1, "abc");
$sth->execute; Results in this output:
So the |
confirming behavior of this attribute before and after execution on prepared statements, with and without bound values. and confirming that no segfaults happen (gh perl5-dbi#447)
Thanks for your continued attention to this issue! I was thinking something like this, to really flesh out the expected behavior of the |
confirming behavior of this attribute before and after execution on prepared statements, with and without bound values. and confirming that no segfaults happen (gh perl5-dbi#447)
confirming behavior of this attribute before and after execution on prepared statements, with and without bound values. and confirming that no segfaults happen (gh perl5-dbi#447)
Okay. The tests I wrote are passing under the versions I reported, when placeholder indexes in In this test I was not able to reproduce the segfault in my test. A bit mystified, because it is quite repeatable in its original context. Perhaps later I will find a way to minimize that. |
@myrrhlin yes please try against my fix |
confirming behavior of this attribute before and after execution on prepared statements, with and without bound values.
I've finished cleaning up the tests and made a PR for those. If I have any extra time going forward I will try to isolate the segfault into another test. Sorry I don't have access to a clean box to install a fresh mysql and build Thanks again for your stewardship efforts. |
Thanks
You could use a generic Ubuntu container like |
confirming behavior of this attribute before and after execution on prepared statements, with and without bound values.
DBD::mysql version
4.050
MySQL client version
8.0.39
Server version
8.0.39-0ubuntu0.20.04.1
Operating system version
Ubuntu 20.04.6 LTS
What happened?
Started work in an older codebase. I tried using
DBI::Log
module in a test script, and got a segfault.As you can see, the first query, using
$dbh->do()
is fine. The second query is an$sth->execute(42)
on aSELECT
statement with one placeholder, an integer id field, that causes the segfault. (Note: nowhere did we use$sth->bind_param
.)I used perl debugger to find the offending statement, and it's this one:
So this module uses the statement handle attribute
ParamValues
to find out what the bound parameter values were. This is a sometimes supported interface from DBI. It's expected to return a hashref, whereHowever, it should be noted that:
So, it's clear to me that
DBI::Log
should not be trying to read this data before execution, because for some drivers (including obviously mysql), the data won't be there yet. Regardless, if the attribute value wasundef
, as DBI docs suggest, the line causing the segfault would not have been executed. To have entered theif
block, the attribute must have had some true value.In the debugger again, I find what it is:
So the
ParamValues
attribute had the true value{ 0 => undef }
.However, that data structure was not a "pure-perl" clean hashref, as dereferencing it in list context caused the segfault. Alternative code to copy the hash such as this did not trigger a segfault:
Now, reading statement handle docs for
DBD::mysql
there is no mention ofParamValues
attribute, which raises some question whether it is supported at all. The docs do confirm however that:Testing shows that after execution, the attribute is populated with e.g.,
{ 0 => 42 }
, which is almost useful, but non-compliant with the DBI docs (which required the first argument to be under key1
).So we have these problems:
under no circumstance should accessing the parameter value, regardless of context, cause a segfault.
before execution, if we can't provide the values yet, the attribute value should be
undef
.after execution, it should probably be using integer keys starting with 1, e.g.
{ 1 => 42 }
Other information
Testing performed with system perl on Ubuntu 20.04 LTS :
Apologies I did not have time to try to replicate the failure with a newer version. If I get more time I will try to do that.
Issue #353 also suggests trouble with the xs building the data structures tied behind the statement handle attributes. Perhaps related.
The text was updated successfully, but these errors were encountered: