Jump to content

PHP 8 Socket_Write Broken Pipe


Tooncinator

Recommended Posts

Hello.

I am tasked with updating this program to PHP 8, but I am having problems. Specifically the one I want help with is this one, logged by /var/log/lighttpd-error.log:

1969-12-31 18:11:12: (../src/mod_fastcgi.c.449) FastCGI-stderr:PHP Warning: socket_write(): unable to write to socket [32]: Broken pipe in /program/www/classes/ipc.class.php on line 46

It may produce this several times before PHP says Maximum execution time of 30 seconds exceeded. There are also some errors that read "PHP Warning: Trying to access array offset on value of type null in /program/www/main.php on line 246", but that doesn't seem relevant. In case it is, here I will link that portion:

# Fatal error handler.
function fatal_error_handler () {
   $last_error = error_get_last();

   if ($last_error['type'] === E_ERROR) { //this is line 246 where the warning is thrown
      error_handler(E_ERROR, $last_error['message'], $last_error['file'], $last_error['line']);
   }
}

As for the socket, I am not very educated on sockets. This is a server interacting with a Pi running Buildroot Linux, the Pi is running Python code, and there is interprocess communication going on between the two. I believe almost all the communication works fine, but notably the data stream is blank, and I suspect that is what is not being written. The request for the data stream is get_display_and_indicators. I have verified Python is receiving it okay and sending it back with this code:

def ipc_get_both (self, skt, data):
      # Send all rows.
      disp_data = []

      for row in range(self.rows):
         row_data = self.remote.get_param_value('Display', row)
         log_info('Row: ' + str(self.translate(row_data)))
         disp_data.append(self.translate(row_data))

      skt.send({
         'reply_to': data['request_type'],
         'rows': self.rows,
         'columns': self.cols,
         'data': disp_data,
         'indicator_states': self.remote.get_param_value('Indicator States'),
         'cursor_row': self.remote.get_param_value('Cursor Row')[0],
         'cursor_column': self.remote.get_param_value('Cursor Column')[0],
         'cursor_enabled': self.remote.get_param_value('Cursor Enabled')
      }, json_encoding = 'latin1')
      log_info('Sent.')

That will produce this a little quicker than every second, which is how it's supposed to work.

1969-12-31 18:56:27 <INFO > : {'request_type': 'get_display_and_indicators'}
1969-12-31 18:56:27 <INFO > : Row:   B0: 0.0     G    0GPM
1969-12-31 18:56:27 <INFO > : Row:  B33: 0.000   G  0.0GPM
1969-12-31 18:56:27 <INFO > : Row:  Set: B10.0 Got:    N/A
1969-12-31 18:56:27 <INFO > : Row: Owed: 0.000 G
1969-12-31 18:56:27 <INFO > : Row:  Spd: N/A
1969-12-31 18:56:27 <INFO > : Row:  Status: LOCAL OFF
1969-12-31 18:56:27 <INFO > : Sent.

And I think PHP is receiving it okay, in www/remotedisplay.php we have:

while (true) {
   $data = $ipc->request(['request_type' => 'get_display_and_indicators'], false);
   $log_file = '/var/log/indicatordebug.txt';
   file_put_contents($log_file, PHP_EOL . $data, FILE_APPEND);

   echo 'data: ' . $data . $end_message;
   flush();
   ob_flush();

   usleep(1000 * 500);
}

Which produces the attached file indicatordebug.txt.

So with all this information, and the attached file ipc.class.txt, what could be causing the socket to not be able to write? It seems to display the last one that got sent after I shut the python program down, which is very weird to me.

Please let me know if you need any other code.

indicatordebug.txt ipc.class.txt

Link to comment
Share on other sites

1 hour ago, Tooncinator said:

1969-12-31 18:11:12: (../src/mod_fastcgi.c.449) FastCGI-stderr:PHP Warning: socket_write(): unable to write to socket [32]: Broken pipe in /program/www/classes/ipc.class.php on line 46

This means the remote end of the socket closed its connection while PHP was still trying to write to it.

Why? I can't tell you. Could be the remote code bailed and the program quit. Could be it closed the connection normally but your PHP isn't "smart enough" to recognize this happened. You'll have to look into why the Python side stopped.

1 hour ago, Tooncinator said:

PHP Warning: Trying to access array offset on value of type null in /program/www/main.php on line 246

That's a bug in the code: it thinks a value is an array when it's actually null - probably as a result of some other operation failing.

Improve the error handling in that area of code, then find out what the underlying problem is and fix it.

Link to comment
Share on other sites

Thank you for your answer, requinix. I am new to PHP and knowing anything at all about this problem is greatly helpful.

This code was working in PHP 7 perfectly; I am not sure if it was my own changes to make it stop giving me errors in PHP 8 that made this socket writing stuff break, or if updating to PHP 8 itself caused the error. I guess that's something else I could check. I don't think it's the python side because in Raspbian in PHP 7 it was displaying fine.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.