php / php-src

The PHP Interpreter
https://www.php.net
Other
38.32k stars 7.76k forks source link

Memory allocation error: pdo-odbc #15113

Closed ALPBRCH closed 2 months ago

ALPBRCH commented 4 months ago

Hello,

Since php version 8.1, the following error occurs when writing to the DB: Fehler SQL: SQLSTATE[HY001]: Memory allocation error: [IBM][System i Access ODBC-Treiber]Speicherzuordnungsfehler. (SQLPrepare[0] at /builddir/build/BUILD/php-8.2.21/ext/pdo_odbc/odbc_driver.c:200).

Situation: Linux-Oracle-Server: PHP 8.3.9 (x86_64) IBM iSeries: ibm-iaccess-1.1.0.28-1.0.x86_64

No problems with php-8.0!

Best regards Jürgen Immel

cmb69 commented 4 months ago

This is the repository of the German translation – I'm transferring to php-src.

cmb69 commented 4 months ago

The mentioned line would be

https://github.com/php/php-src/blob/482ca6c19c4d776c37bcdd5823edd524f4199cfa/ext/pdo_odbc/odbc_driver.c#L200-L200

Maybe @NattyNarwhal has an idea what might be wrong there. Other than that, we probably need a small self-contained reproduce script, and perhaps an ODBC trace would also be helpful.

ALPBRCH commented 4 months ago

test_odbc.txt This is a simple example of a script. Out of 10 inserts, 3 work.

NattyNarwhal commented 4 months ago

Do you have the CREATE TABLE definition?

ALPBRCH commented 4 months ago

bestkopf.sql.txt

ALPBRCH commented 4 months ago

Hi, some additional information: Linux Server-> unixODBC.x86_64 2.3.7-1.el8

IBM Power 9 Release V7R3M0

NattyNarwhal commented 3 months ago

I'll take a look at this this week; I was on vacation last week.

NattyNarwhal commented 3 months ago

I'm confused because I look at that CREATE TABLE definition and it's for MySQL, but the driver issue is for Db2i.

ALPBRCH commented 3 months ago

Hi, Sorry, you're right. The create is from Mysql. The DB2 database was created with a DDL description which unfortunately I cannot provide.

Regards, Jürgen Von: Calvin Buckley @.> Gesendet: Donnerstag, 8. August 2024 16:47 An: php/php-src @.> Cc: Jürgen Immel @.>; Author @.> Betreff: Re: [php/php-src] Memory allocation error: pdo-odbc (Issue #15113)

I'm confused because I look at that CREATE TABLE definition and it's for MySQL, but the driver issue is for Db2i.

— Reply to this email directly, view it on GitHubhttps://github.com/php/php-src/issues/15113#issuecomment-2276016037, or unsubscribehttps://github.com/notifications/unsubscribe-auth/A3DGO54UVRB4G42V4CDSG73ZQOAH5AVCNFSM6AAAAABLQEVUKOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENZWGAYTMMBTG4. You are receiving this because you authored the thread.Message ID: @.***>

ALPBRCH commented 3 months ago

Hello, I asked the developer to give me a create or DDL of the tables.

best regards-Jürgen

ALPBRCH commented 3 months ago

bestpos.txt bestkopf.txt Hi, here the DDL of the tables. Regards

ALPBRCH commented 3 months ago

Any news?

NattyNarwhal commented 3 months ago

Sorry about this, I got busy with other projects. I'll take a look this week.

NattyNarwhal commented 3 months ago

That DDS is missing the record format. Can you provide the full PF source, including record formats, or the SQL DDL?

ALPBRCH commented 3 months ago

BESTPOSDD.txt BESTKOPF_DD.txt The record format is in the DDS. The line with “R” stands for record. says the developer

NattyNarwhal commented 3 months ago

I think BESTKOPF is missing the first line that indicates what file it references (the one with REF IIRC); there's the R in position 17 for the record format, and the subsequent lines in position 29 for fields.

ALPBRCH commented 3 months ago

[BESTKOPF_DD.txt](https://github.com/user-attachments/files/16832538/BESTKOPF_DD.txt)

ALPBRCH commented 3 months ago

REF01.txt

NattyNarwhal commented 2 months ago

There was some SEU issues in the copy and paste, but after manually cleaning it up, I've managed to create the tables on my system. I haven't been able to reproduce the issue on my systems yet (server with i 7.2, client with PHP 8.3.10 on macOS 14). I'll try to test on Linux soon.

ALPBRCH commented 2 months ago

Sorry, unfortunately I had no other option to pass on the data. I also suspect it is problem with php on Linux OS

NattyNarwhal commented 2 months ago

Testing on a Fedora system, looks like I have ibm-iaccess-1.1.0.28-1.0.x86_64 installed. Testing with both PHP 8.2 and 8.3, I can't seem to reproduce it.

@kadler Since this involves the IBM i ODBC driver, do you have any suggestions? I can provide the cleaned-up DDS.

ALPBRCH commented 2 months ago

I have set up a new virtual server with Linux Fedora.
Php 8.3 ibm-iaccess-1.1.0.28.1.0.x86_64

Memory allocation error: [IBM][System i Access ODBC Driver]Memory allocation error. (SQLPrepare[0] at /builddir/build/BUILD/php83-php-pecl-swoole5-5.1.4/swoole-5.1.4/thirdparty/php83/pdo_odbc/odbc_driver.c:207)

cmb69 commented 2 months ago

So this might be a Swoole issue. @ALPBRCH, have you tried without Swoole (i.e. plain PHP)?

ALPBRCH commented 2 months ago

Yes, same error

ALPBRCH commented 2 months ago

plain php 8.2 SQLSTATE[HY001]: Memory allocation error: [IBM][System i Access ODBC-Treiber]Speicherzuordnungsfehler. (SQLPrepare[0] at /builddir/build/BUILD/php-8.2.23/ext/pdo_odbc/odbc_driver.c:200)

kadler commented 2 months ago

Can you get an ODBC trace? https://www.easysoft.com/support/kb/kb00945.html

ALPBRCH commented 2 months ago

odbc.log

kadler commented 2 months ago

odbc.log

This memory allocation error occurred while getting this trace?

cmb69 commented 2 months ago

There are lot of diagnostics: DIAG [HY001] [IBM][System i Access ODBC-Treiber]Speicherzuordnungsfehler.

"Speicherzuordnungsfehler" likely means "memory allocation error".

kadler commented 2 months ago

Ohhhh, ok. I don't think my coffee had set in sufficiently yet and for some reason I was expecting a crash.

Well, unfortunately the odbc.log doesn't provide much details. It seems to be passing perfectly normal SQL statements to SQLPrepare. The statement is cut off, but unixODBC says they are SQL_NTS and of reasonable length so I'm not sure why it would be failing.

I think next step is a driver trace:

$ cwbtrc /dt:1

$ php recreate-script.php

$ cwbtrc /dt:0

If you're running the PHP script as another user (eg. under Apache) you'll need to run cwbtrc as that user, using sudo. The log files will be under ~/.iSeriesAccess for the user running the recreate named cwbdetail64--.csv.

cmb69 commented 2 months ago

Interestingly, when the DBC handle is allocated, the driver prints UNICODE Using encoding ASCII 'UTF-8' and UNICODE 'UCS-2LE'. However, the trace is encoded as ISO-8859-?. Is it possible that there are char vs. unsigned char issues on IBM i? If so, https://github.com/php/php-src/commit/aa58db723221ec891d4432621003bfa55dc15edf#diff-ba7720c5ed6bf598d7e064a5f2b45ba5b80a04a3412400e1681660a777fd0fcaR195 might be relevant.

ALPBRCH commented 2 months ago

cwbdetail64-php-696b.csv

kadler commented 2 months ago

Ok, so this is a rather misleading error as for some reason in this code path any conversion error results in returning a a memory allocation error. The actual problem is that the data we're getting is in ISO-8859-1, but the driver is treating it as UTF-8. eg. "Büc" is encoded as 42FC63, but should be 42C3BC63.

So there's two solutions here:

  1. switch the driver encoding (eg. use CCSID=819 connection option) to what PHP is sending
  2. get PHP to send UTF-8 that the driver expects

Personally, I wouldn't want to go backwards from UTF-8, but I don't know anything about how PHP encodes its strings. Probably back to @NattyNarwhal from here and I'll look at fixing the misleading error to make diagnostics easier in the future.

NattyNarwhal commented 2 months ago

I'm assuming by default, your Linux system's locale is a UTF-8 one, I'm not sure how the Db2i driver picks the default encoding (it can be overridden with CCSID= as you say though), and PHP itself will have a default charset of UTF-8, but pages can always override this; i.e. header("Content-Type: text/html; charset=iso-8859-1").

My guess is knowing what I know, you're getting legacy encoding strings from somewhere (i.e. an HTML form on a page marked as ISO-8859-1 will submit text in that encoding to the form target), and the driver is expecting UTF-8. The two ways to deal with this if so is:

  1. Make sure you're getting UTF-8 the whole way through, at least until it hits Db2 (probably the best for correctness)
  2. Force the driver into using the legacy encoding that you're dealing with (easy workaround, but it can be confusing and inconsistent - what parts of the process are UTF-8 and what isn't?)
kadler commented 2 months ago

I'm assuming by default, your Linux system's locale is a UTF-8 one, I'm not sure how the Db2i driver picks the default encoding

The driver uses the locale's encoding, from nl_langinfo(CODESET).

ALPBRCH commented 2 months ago

Hello, Many, many thanks to everyone for the help. Unfortunately, we have some legacy issues when it comes to coding. End-to-end encoding in UTF-8 is in the works. Thanks again. Best regards