Displaying running PHP 7.4 stack trace on Red Hat UBI Container

 When running a PHP application in container, sometimes we need to find out what bottleneck is impacting the app's response time. This post documents the approach to do so, but still requiring access to root user in the container. The platform where I was running the PHP app is Red Hat Openshift Community (OKD) version 3.6, which is still using docker to run containers instead of Red Hat's podman.

Preparation - Locating the pod and the worker node

  1. Open openshift's console home
  2. Select your Project (namespace) containing the pod
  3. Select Application => Pods





  4. Choose your pod from the list.



  5. Note the worker node hosting the pod.


Install php debug-info

Normally, the openshift platform doesn't allow containers running as root. So are in this case, the container will be running as normal random-uid-user. But we need to install php debuginfo packages, thus we need to run as root. The trick is to access the node running the application's pods, so we need admin access on the worker node to do so.  I am assuming you already have root access on the worker node.
  1. Access the worker node, locate the pod's container.


  2. Run bash shell inside the container as root user
    docker exec -it -u root <containerid> bash
  3. Install debuginfo for php
    dnf debuginfo-install php
  4. Exit the bash shell.

Install php gdbinit

Next, we need to use gdbinit from php sources.
  1. Open this url in your web browser. Replace PHP version with the one matching the one being used. Url : https://github.com/php/php-src/blob/PHP-7.4.30/.gdbinit
  2. Click on the 'Raw' button. The resulting url is like : https://raw.githubusercontent.com/php/php-src/PHP-7.4.30/.gdbinit
  3. Open pod's terminal from openshift console (or use oc rsh)
  4. Get the file using wget :
    wget https://raw.githubusercontent.com/php/php-src/PHP-7.4.30/.gdbinit

Displaying stack trace

  1. Check pid of running apache process
    ps afxw
  2. Restart apache2 process 
    apachectl -k graceful
  3. Check current pid of running apache processes
    ps afxw
  4. Now, check the pid list from step 1 and 3. The common number between these two list means these pids were not being restarted (still running some process), so debug them (debug only the child, not the parent)
    gdb -p pid
  5. Inside the gdb shell, dump stack trace
    dump_bt executor_globals.current_execute_data
  6. Quit the gdb (otherwise the php script would not continue)
    quit
    y

Closing remarks

This procedure is more generic than the previous tricks I have shared in this blog. This might not work on podman-based containers. Outside openshift ecosystem, php-fpm already has built in capability to dump stack trace for running scripts longer than some time treshold.

Comments

Popular posts from this blog

Long running process in Linux using PHP

Reverse Engineering Reptile Kernel module to Extract Authentication code

SAP System Copy Lessons Learned