#!/bin/bash

CLEAR_FLAG=0
STACK_FLAG=0
SCRIPT_PATH=`dirname $0`
SYS=`uname -s`

function get_php_version()
{
    echo `/proc/$1/exe -i 2>&1 | grep -i 'PHP Version' | uniq | awk '{print $4}'`
}

function get_php_address() 
{
GDB=${GDB:-/usr/bin/gdb}

#if $GDB -nx --quiet --batch --readnever > /dev/null 2>&1; then
#    readnever=--readnever
#else
#    readnever=
#fi

sapi_globals="print &(sapi_globals)"
sapi_globals_1="print &(sapi_globals.request_info.path_translated)"
executor_globals="print &(executor_globals)"
executor_globals_1="print &(executor_globals.current_execute_data)"
executor_globals_10="print (executor_globals.current_execute_data)"
executor_globals_11="print &(executor_globals.current_execute_data->function_state.function)"
executor_globals_110="print (executor_globals.current_execute_data->function_state.function)"
executor_globals_111="print &(executor_globals.current_execute_data->function_state.function->common.function_name)"
executor_globals_12="print &(executor_globals.current_execute_data->prev_execute_data)"
executor_globals_13="print &(executor_globals.current_execute_data->op_array)"
executor_globals_130="print (executor_globals.current_execute_data->op_array)"
executor_globals_131="print &(executor_globals.current_execute_data->op_array->filename)"
executor_globals_14="print &(executor_globals.current_execute_data->opline)"
executor_globals_140="print (executor_globals.current_execute_data->opline)"
executor_globals_141="print &(executor_globals.current_execute_data->opline->lineno)"

#$sapi_globals
#$sapi_globals_1
#$executor_globals
#$executor_globals_1
#$executor_globals_10
#$executor_globals_11
#$executor_globals_110
#$executor_globals_111
#$executor_globals_12
#$executor_globals_13
#$executor_globals_130
#$executor_globals_131
#$executor_globals_14
#$executor_globals_140
#$executor_globals_141

# Run GDB, strip out unwanted noise.
$GDB --quiet $readnever -nx /proc/$1/exe $1 <<EOF 2>&1 | 
set width 0
set height 0
set pagination no
$sapi_globals
$executor_globals
EOF
/bin/sed -n \
    -e 's/^\((gdb) \)*//' \
    -e '/^\$/p' \
    -e '/^Thread/p' | awk '{print $NF}'

}
function check_pid_exist(){
    case $SYS in
        Darwin*)
            if [ "`ps -p ${PID} -o pid=`" = "" ];then
                return 0;
            fi
            ;;
        *)
            if [ -n "${PID}" ] && [ ! -d "/proc/${PID}" ]; then
                return 0;
            fi
            ;;
    esac
    return 1;
}

while getopts ":p:s"  arg
do
    case "$arg" in
        "p")
            PID=$OPTARG
            ;;  
        "s")
            STACK_FLAG=1
            ;;  
        "l" | "e" | "v")
        ;;
        *)
            break
            ;;
    esac
done

if [ -n "$PID" ]; then
    check_pid_exist
    if [ $? -eq 0 ]; then
        echo "Oops, process ${PID} does not exist."
        exit 1
    fi
fi
if [ $STACK_FLAG -eq 1 ] && [ "$SYS" = "Darwin" ];then
    echo "Dump stack on Mac OS X is not supported now ..."
    exit 1;
fi

if [ $STACK_FLAG -eq 1 ] ; then
    if [ -z $PID ] ; then
        echo "Oops, need a pid"
        exit 1
    fi
    #Try to get status from phptrace extension first
    "$SCRIPT_PATH/trace-php" $@ && exit 0;
    echo "STACK ERROR: Can not fetch PHP status from extension, fallback to get stack by ptrace"
    declare -i retry=1
    while ((retry<=10))
    do
        version=$(get_php_version $PID)
        if [ $? -eq 0 ] ; then
            lines=$(get_php_address $PID)
            if [ $? -eq 0 ] ; then
                params=($lines)
                params_num=${#params[@]}
                if [ $params_num -eq 2 ]; then
                    "$SCRIPT_PATH/trace-php" $@ --php-version $version --sapi-globals ${params[0]} --executor-globals ${params[1]}
                    break
                fi
            fi
        fi
        let ++retry
        sleep 0.1
    done

    if [ $retry -ge 11 ] ; then
        echo "can not print php stack"
    fi
else
    "$SCRIPT_PATH/trace-php" $@
fi

