C ++程序意外死亡

时间:2012-06-21 23:29:17

标签: c++ exception ubuntu exception-handling

我有一个c ++代码似乎每天晚上从凌晨2点到早上6点因某种原因而死。我调查了日志文件,发现死亡不是由于数据库错误造成的。也没有例外。我检查了系统日志,c ++中没有任何内容。我正在使用Ubuntu服务器来运行c ++。我在这里添加我的代码请帮助我。

int main(int argc, char *argv[]) {
    try {
        int sockfd, portno, net_socket2, portno2;
        struct sockaddr_in serv_addr;
        struct sockaddr_in si_output2;
        struct hostent *server;
        int iof;

        int n, udp_size;

        unsigned char receivedMessage[256];
        unsigned char buffer[50];

        // register the signal (exception) handler
        signal(SIGINT, SIGINThandler);

        // Log on //////////////////////////////////////////////////////////////////////////////////////////////////////
        printf("Logging on\n");
        log("Logging on");
        portno = SERVER_PORT;
        sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (sockfd < 0) {
            log("ERROR opening socket");
            error("ERROR opening socket");
        }
        printf("Socket opened \n");
        log("Socket opened");
        bzero((char *) &serv_addr, sizeof (serv_addr)); //clear the structure
        serv_addr.sin_family = AF_INET;
        if (inet_aton(SERVER_IP, &serv_addr.sin_addr) == 0) {
            printf("inet_aton() failed \n");
            log("inet_aton() failed ");
            return 0;
        }

        serv_addr.sin_port = htons(portno); //set the host port
        const struct sockaddr *to_cast = (struct sockaddr *) &serv_addr;
        printf("Connecting to %s %d on port %d \n", SERVER_IP, serv_addr.sin_addr.s_addr, portno);
        log("Connecting to port on the server");
        if (connect(sockfd, to_cast, sizeof (serv_addr)) < 0) {
            log("Error connecting");
            error("ERROR connecting\n");
        }

        if ((fcntl(sockfd, F_GETFL, 0)) != -1)
            fcntl(sockfd, F_SETFL, iof | O_NONBLOCK);
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        // now open udp socket to receive messages from host /////////////////////////////////////////////////////////////
        int MESSAGE_PORT = 6001;
        if ((net_socket2 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
            log("Message socket problem");
            perror("setsockopt");
            exit(1);
            printf("message socket problem \n");
            close(net_socket2);
            return 0;
        }
        memset((char*) &si_output2, sizeof (si_output2), 0);
        si_output2.sin_family = AF_INET;
        si_output2.sin_port = htons(MESSAGE_PORT);
        si_output2.sin_addr.s_addr = INADDR_ANY;

        //bind socket for incomming messages
        log("bind socket for incomming messages");
        if (bind(net_socket2, (struct sockaddr *) &si_output2, sizeof (struct sockaddr)) == -1) {
            log("Socket 2 bind failed");
            printf("socket 2 bind failed \n");
            close(net_socket2);
            return 0;
        }
        //set to non blocking
        if ((iof = fcntl(net_socket2, F_GETFL, 0)) != -1)
            fcntl(net_socket2, F_SETFL, iof | O_NONBLOCK);

        //In the above INADDR_ANY means the message could come from anywhere, you
        //would have to select a free port for MESSAGE_PORT
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        // Send the logon message
        log("Send the logon message");
        unsigned char* logonMessage = msgLogon();
        //cout << "\nLogon Message Begin: ";
        displayByteArray(logonMessage, 38);
        //cout << "\nLogon Message End\n";
        n = write(sockfd, logonMessage, 38);
        if (n < 0) {
            log("ERROR writing to socket");
            error("ERROR writing to socket");
        }
        // Assume we are logged in now so start receiving messages ////////////////////////////////////////////////////////
        log("Assume we are logged in now so start receiving messages");
        while (true) {
            // Check for incomming message from etsl //
            bzero(receivedMessage, 256); //clear the received message
            n = read(sockfd, receivedMessage, 255);
            if (n > 0) {

                //cout << "\nReceived Message Begin: ";
                //displayByteArray(receivedMessage, n);
                //cout << "\nReceived Message End\n";

                MsgReply message = MsgReply(receivedMessage, n);

                messageHandler(message);

                if (message.getValue()) { //If we can get a reply message

                    unsigned char* replyMessage = message.getReplyMessage();

                    //int m = sizeof(replyMessage)/sizeof(replyMessage[0]);
                    int m = message.getReplyMessageLength();
                    //cout << "\nReply Message Length: m: " << m;
                    n = write(sockfd, replyMessage, m);
                    if (n < 0) {
                        log("ERROR writing to socket");
                        error("ERROR writing to socket");
                    }

                } else {
                    log("Did not reply to this message");
                    //cout << "\nDid not reply to this message\n";
                }
            }

            if (sendLogoff) {
                //cout << "\nreceived a control c";
                log("Send the logoff message");
                // Send the logon message
                unsigned char* logoffMessage = msgLogoff();
                //cout << "\nLogoff Message Begin: ";
                displayByteArray(logoffMessage, 38);
                //cout << "\nLogoff Message End\n";
                n = write(sockfd, logonMessage, 38);
                if (n < 0) {
                    log("ERROR writing to socket");
                    error("ERROR writing to socket");
                }
                sendLogoff = false;
            }           
        }


        log("Exit main block on success");
        return EXIT_SUCCESS;
    } catch (const std::exception& ex) {
        //cout<< ex.what();    
        log(ex.what());
    } catch (const std::string& ex) {
        //cout << ex;
        log(ex);
    } catch (...) {
        log("unknown exception");
    }
}

这是MessageHandler代码

void messageHandler(MsgReply& message) {

string msgStr = byteArrayToHexString(message.getReceivedMessage(), 2 * message.getReceivedMessageLength());

int type = messageType(msgStr);

if ((type == 220) || (type == 221)) {

    string subMsg;
    string replyMsgStr;

    //message type
    replyMsgStr = "0230";

    //bit map
    subMsg = "323A00000A008000";
    replyMsgStr.append(subMsg);

    //processing code
    subMsg = msgStr.substr(24, 6);
    replyMsgStr.append(subMsg);

    //amount
    subMsg = msgStr.substr(30, 12);
    replyMsgStr.append(subMsg);

    //date/time
    subMsg = msgStr.substr(42, 10);
    replyMsgStr.append(subMsg);

    //trace number
    subMsg = msgStr.substr(52, 6);
    replyMsgStr.append(subMsg);

    //local time
    subMsg = msgStr.substr(58, 6);
    replyMsgStr.append(subMsg);

    //local date
    subMsg = msgStr.substr(64, 4);
    replyMsgStr.append(subMsg);

    //settelment date
    subMsg = msgStr.substr(72, 4);
    replyMsgStr.append(subMsg);

    //retrieval reference number
    subMsg = msgStr.substr(108, 24);
    replyMsgStr.append(subMsg);

    //responce code
    subMsg = msgStr.substr(144, 4);
    replyMsgStr.append(subMsg);

    //transaction currency code
    subMsg = "0554";
    replyMsgStr.append(subMsg);

    // Get message length
    int length = replyMsgStr.length();
    length = length / 2;
    string msgLength = intToHex(length);
    replyMsgStr = msgLength.append(replyMsgStr);

    message.setReplyMessage(replyMsgStr);


}

if (type == 100) {
    string subMsg;
    string replyMsgStr;

    string processing_code = msgStr.substr(24, 6); // The processing code
    string amount = msgStr.substr(30, 12); // The amount
    string transaction_number = msgStr.substr(52, 6); // The trace number
    string magnetic_number = msgStr.substr(106, 16); // The track2data
    string database = msgStr.substr(112, 2); // Which database we query
    string etsl_number = hexStringToAsciiString(msgStr.substr(130, 24), 12); // The retreival reference number
    string terminal_number = hexStringToAsciiString(msgStr.substr(170, 30), 15);
    ; // The card acceptor id code

    string return_string;
    string return_code;
    string return_value;

    string pinpadMessage;
    string terminalMessage;
    string receiptText1;
    string receiptText2;
    string tmLength;

    // Get response code
    bool rewardOnPurchase;
    stringstream ss;
    double numDouble;
    int numInt;
    ss << database;
    ss >> numInt;

    if (numInt == 10) {
        //cout << "\nProwze Database";

        replyMsgStr = "0110B23A4481AAE180000000000000000080";

        subMsg = msgStr.substr(24, 130);
        replyMsgStr = replyMsgStr.append(subMsg);

        // Get Processing Code and Reward Amount
        rewardOnPurchase = false;
        return_string = prowze_db(processing_code, amount, transaction_number, magnetic_number, etsl_number, terminal_number, rewardOnPurchase);
        //cout << "\nreturn_string: " << return_string << "\n\n";
        return_code = return_string.substr(0, 4);
        //return_code = "3035";
        return_value = return_string.substr(4, 8);
        // Convert return value to hex
        return_value = asciiStringToHexString(return_value, 8);

        //cout << "\nprocessing_code: " << processing_code;
        if (atoi(processing_code.c_str()) == 13000) {
            //cout << "\nReward Transaction";   

            if (atoi(return_code.c_str()) == 3030) {
                //cout << "\nAccepted Reward Transaction";

                //terminalMessage = "20202020414343455054454420202020";
                terminalMessage = terminalMessage.append("2052455741524420");
                terminalMessage = terminalMessage.append(return_value);
                terminalMessage = terminalMessage.append("20202020414343455054454420202020");
                terminalMessage = terminalMessage.append("594F55522052455741524420");
                terminalMessage = terminalMessage.append(return_value);
                terminalMessage = terminalMessage.append("50524F575A452052455741524453204341534821");
                string tmLength = "0072";
                terminalMessage = tmLength.append(terminalMessage);
            } else if (atoi(return_code.c_str()) == 3537) {
                //cout << "\nDeclined Reward Transaction: Card On Hold";

                terminalMessage = "202043415244204F4E20484F4C442020";
                terminalMessage = terminalMessage.append("202020204445434C494E454420202020");
                terminalMessage = terminalMessage.append("2020202043415244204F4E20484F4C4420202020");
                terminalMessage = terminalMessage.append("50524F575A452052455741524453204341534821");
                tmLength = "0072";
                terminalMessage = tmLength.append(terminalMessage);
            } else {
                //cout << "\nDeclined Reward Transaction";

                terminalMessage = "202020204445434C494E454420202020";
                terminalMessage = terminalMessage.append("202020204445434C494E454420202020");
                terminalMessage = terminalMessage.append("594F5552205245574152442024303030302E3030");
                terminalMessage = terminalMessage.append("50524F575A452052455741524453204341534821");
                tmLength = "0072";
                terminalMessage = tmLength.append(terminalMessage);
            }

        } else if (atoi(processing_code.c_str()) == 3000) {
            //cout << "\nPurchase Transaction";

            if (atoi(return_code.c_str()) == 3030) {
                //cout << "\nAccepted Purchase Transaction";

                // Perform Reward on Purchase
                rewardOnPurchase = true;
                return_string = prowze_db("013000", amount, transaction_number, magnetic_number, etsl_number, terminal_number, rewardOnPurchase);
                //cout << "\nreturn_string: ";
                //return_code = return_string.substr(0,4);
                return_value = return_string.substr(4, 8);
                // Convert return value to hex
                return_value = asciiStringToHexString(return_value, 8);

                terminalMessage = "41434345505420574954482053494720";
                terminalMessage = terminalMessage.append("41434345505420574954482053494720");
                terminalMessage = terminalMessage.append("2020414343455054205749544820534947202020");
                terminalMessage = terminalMessage.append("594F55522052455741524420");
                terminalMessage = terminalMessage.append(return_value);
                string tmLength = "0072";
                terminalMessage = tmLength.append(terminalMessage);
            } else if (atoi(return_code.c_str()) == 3537) {
                //cout << "\nDeclined Reward Transaction: Card On Hold";

                terminalMessage = "202043415244204F4E20484F4C442020";
                terminalMessage = terminalMessage.append("202020204445434C494E454420202020");
                terminalMessage = terminalMessage.append("2020202043415244204F4E20484F4C4420202020");
                terminalMessage = terminalMessage.append("50524F575A452052455741524453204341534821");
                tmLength = "0072";
                terminalMessage = tmLength.append(terminalMessage);
            } else {
                //cout << "\nDeclined Purchase Transaction";

                terminalMessage = "202020204445434C494E454420202020";
                terminalMessage = terminalMessage.append("202020204445434C494E454420202020");
                terminalMessage = terminalMessage.append("594F5552205245574152442024303030302E3030");
                terminalMessage = terminalMessage.append("50524F575A452052455741524453204341534821");
                tmLength = "0072";
                terminalMessage = tmLength.append(terminalMessage);

            }


        } else {
            //cout << "\nUnkown Transaction Type";

            // Return Code
            return_code = "3035";

            // Decline message
            terminalMessage = "202020204445434C494E454420202020";
            terminalMessage = terminalMessage.append("202020204445434C494E454420202020");
            terminalMessage = terminalMessage.append("594F5552205245574152442024303030302E3030");
            terminalMessage = terminalMessage.append("50524F575A452052455741524453204341534821");
            tmLength = "0072";
            terminalMessage = tmLength.append(terminalMessage);
        }

        // Append Return Code
        replyMsgStr = replyMsgStr.append(return_code);

        //subMsg = msgStr.substr(154,166);
        //154 = 
        subMsg = msgStr.substr(154);
        replyMsgStr = replyMsgStr.append(subMsg);

        //Check to see if the message is a pre-auth
        //Not pre-auth bit map: 323A4481A8E18000
        //pre-auth bit map: 323A4481A8E18080
        //cout << "\nCheck bit 15 of bitmap to see if message is a pre-auth: " << msgStr.substr(22,1);
        if (!((msgStr.substr(22, 1)).compare("8"))) {
            //cout << ": Therefore pre-auth message";
            int aa = replyMsgStr.length();
            aa = aa - 10;
            replyMsgStr = replyMsgStr.substr(0, aa);
        } else //cout << ": Therefore non pre-auth message";

            // Append Terminal Message
            replyMsgStr = replyMsgStr.append(terminalMessage);

        // Get message length
        int length = replyMsgStr.length();
        length = length / 2;
        string msgLength = intToHex(length);
        replyMsgStr = msgLength.append(replyMsgStr);

        message.setReplyMessage(replyMsgStr);


    } else if (numInt == 20) {
        //cout << "\nBarter Database";

        replyMsgStr = "0110B23A4481AAE180000000000000000080";

        subMsg = msgStr.substr(24, 130);
        replyMsgStr = replyMsgStr.append(subMsg);

        // Get Return Code
        //cout << "\nprocessing_code: " << processing_code << "\n";
        if (atoi(processing_code.c_str()) == 3000) {
            return_code = barter_db(processing_code, amount, transaction_number, magnetic_number, etsl_number, terminal_number);
        } else {
            return_code = "3035";
        }
        //cout << "\nreturn_code: " << return_code;         

        if (atoi(processing_code.c_str()) == 3000) {
            //cout << "\nPurchase Transaction";

            if (atoi(return_code.c_str()) == 3030) {
                //cout << "\nAccepted Purchase Transaction";                    

                //terminalMessage = "20202020414343455054454420202020";     //ACCEPTED
                terminalMessage = "41434345505420574954482053494720"; //ACCEPT WITH SIG
                terminalMessage = terminalMessage.append("41434345505420574954482053494720"); //ACCEPT WITH SIG
                terminalMessage = terminalMessage.append("42415254455253504143452053484F5050494E47"); //BARTERSPACE SHOPPING
                terminalMessage = terminalMessage.append("2020202042415254455253504143452020202020"); //BARTERSPACE
                string tmLength = "0072";
                terminalMessage = tmLength.append(terminalMessage);
            } else if (atoi(return_code.c_str()) == 3537) {
                //cout << "\nDeclined Purchase Transaction: Card On Hold";

                terminalMessage = "202043415244204F4E20484F4C442020";
                terminalMessage = terminalMessage.append("202020204445434C494E454420202020");
                terminalMessage = terminalMessage.append("42415254455253504143452053484F5050494E47");
                string tmLength = "0052";
                terminalMessage = tmLength.append(terminalMessage);
            } else {
                //cout << "\nDeclined Purchase Transaction";

                terminalMessage = "202020204445434C494E454420202020";
                terminalMessage = terminalMessage.append("202020204445434C494E454420202020");
                terminalMessage = terminalMessage.append("42415254455253504143452053484F5050494E47");
                string tmLength = "0052";
                terminalMessage = tmLength.append(terminalMessage);

            }

        } else {
            //cout << "\nUnkown Transaction Type";

            // Return Code
            return_code = "3035";

            // Decline message
            terminalMessage = "202020204445434C494E454420202020";
            terminalMessage = terminalMessage.append("202020204445434C494E454420202020");
            terminalMessage = terminalMessage.append("42415254455253504143452053484F5050494E47");
            string tmLength = "0052";
            terminalMessage = tmLength.append(terminalMessage);
        }

        // Append Return Code
        replyMsgStr = replyMsgStr.append(return_code);

        //subMsg = msgStr.substr(154,166);
        subMsg = msgStr.substr(154);
        replyMsgStr = replyMsgStr.append(subMsg);

        //Check to see if the message is a pre-auth
        //Not pre-auth bit map: 323A4481A8E18000
        //pre-auth bit map: 323A4481A8E18080
        //cout << "\nCheck bit 15 of bitmap to see if message is a pre-auth: " << msgStr.substr(22,1);
        if (!((msgStr.substr(22, 1)).compare("8"))) {
            //cout << ": Therefore pre-auth message";
            int aa = replyMsgStr.length();
            aa = aa - 10;
            replyMsgStr = replyMsgStr.substr(0, aa);
        } else //cout << ": Therefore non pre-auth message";

            // Append Terminal Message
            replyMsgStr = replyMsgStr.append(terminalMessage);

        // Get message length
        int length = replyMsgStr.length();
        length = length / 2;
        string msgLength = intToHex(length);
        replyMsgStr = msgLength.append(replyMsgStr);

        message.setReplyMessage(replyMsgStr);


    } else {
        //cout << "\nCould Not Find Database";

        //Message type and bit map
        replyMsgStr = "0110323A4481AAE18000";

        subMsg = msgStr.substr(24, 130);
        replyMsgStr = replyMsgStr.append(subMsg);

        // Return Code
        //subMsg = barter_db(processing_code, amount, transaction_number, magnetic_number, etsl_number, terminal_number);
        return_code = "3035";
        replyMsgStr = replyMsgStr.append(return_code);

        subMsg = msgStr.substr(154);
        replyMsgStr = replyMsgStr.append(subMsg);

        // Get message length
        int length = replyMsgStr.length();
        length = length / 2;
        string msgLength = intToHex(length);
        replyMsgStr = msgLength.append(replyMsgStr);

        message.setReplyMessage(replyMsgStr);
    }



    // Put in additional user information
    //replyMsgStr = replyMsgStr.append(terminalMessage);

    // Accept message reward
    /*      string terminalMessage = "20202020414343455054454420202020";
                    terminalMessage = terminalMessage.append("20202020414343455054454420202020");
                    terminalMessage = terminalMessage.append("594F5552205245574152442024303030302E3030");
                    terminalMessage = terminalMessage.append("50524F575A452052455741524453204341534821");
                    string tmLength = "0072";
                    terminalMessage = tmLength.append(terminalMessage);
                    replyMsgStr = replyMsgStr.append(terminalMessage);
     */
    // Decline message reward
    /*      terminalMessage = "202020204445434C494E454420202020";
                    terminalMessage = terminalMessage.append("202020204445434C494E454420202020");
                    terminalMessage = terminalMessage.append("594F5552205245574152442024303030302E3030");
                    terminalMessage = terminalMessage.append("50524F575A452052455741524453204341534821");
                    tmLength = "0072";
                    terminalMessage = tmLength.append(terminalMessage);
                    replyMsgStr = replyMsgStr.append(terminalMessage);
     */
    // Accept message purchase
    /*      string terminalMessage = "20202020414343455054454420202020";
                    terminalMessage = terminalMessage.append("202020204445434C494E454420202020");
                    terminalMessage = terminalMessage.append("594F5552205245574152442024303030302E3030");
                    terminalMessage = terminalMessage.append("50524F575A452052455741524453204341534821");
                    string tmLength = "0072";
                    terminalMessage = tmLength.append(terminalMessage);
                    replyMsgStr = replyMsgStr.append(terminalMessage);
     */
    // Decline message purchase
    /*      string terminalMessage = "202020204445434C494E454420202020";
                    terminalMessage = terminalMessage.append("202020204445434C494E454420202020");
                    terminalMessage = terminalMessage.append("594F5552205245574152442024393030302E3030");
                    terminalMessage = terminalMessage.append("50524F575A452052455741524453204341534821");
                    string tmLength = "0072";
                    terminalMessage = tmLength.append(terminalMessage);
                    replyMsgStr = replyMsgStr.append(terminalMessage);
     */


} else if (type == 800) {
    string subMsg;

    string replyMsgStr = "001E08108220000002000000";

    subMsg = "0400000000000000";
    replyMsgStr = replyMsgStr.append(subMsg);

    subMsg = msgStr.substr(40, 16);
    replyMsgStr = replyMsgStr.append(subMsg);

    replyMsgStr = replyMsgStr.append("3030");

    subMsg = msgStr.substr(56, 4);
    replyMsgStr = replyMsgStr.append(subMsg);

    message.setReplyMessage(replyMsgStr);
} else if ((type == 420) || (type == 421)) {
    string subMsg;
    string replyMsgStr = "";

    string processing_code = msgStr.substr(40, 6); // The processing code
    string amount = msgStr.substr(46, 12); // The amount
    string transaction_number = msgStr.substr(68, 6); // The trace number
    string magnetic_number = msgStr.substr(122, 16); // The track2data
    string database = msgStr.substr(128, 2); // Which database we query
    string etsl_number = hexStringToAsciiString(msgStr.substr(146, 24), 12); // The retreival reference number

    subMsg = "0430B23A00000A0080000000004000000000";
    replyMsgStr = replyMsgStr.append(subMsg);

    subMsg = msgStr.substr(40, 48);
    replyMsgStr = replyMsgStr.append(subMsg);

    subMsg = msgStr.substr(146, 24);
    ;
    replyMsgStr = replyMsgStr.append(subMsg);






    if (atoi(database.c_str()) == 10) {
        //cout << "\nChecking prowze database for reversal\n";
        subMsg = prowze_db_rev(processing_code, amount, transaction_number, magnetic_number, etsl_number);
        //cout << "\nreturnCode: " << subMsg << "\n";
    } else if (atoi(database.c_str()) == 20) {
        //cout << "\nChecking barter database for reversal\n";
        subMsg = barter_db_rev(processing_code, amount, transaction_number, magnetic_number, etsl_number);
        //cout << "\nreturnCode: " << subMsg << "\n";
    } else {
        subMsg = "3030";
    }
    replyMsgStr = replyMsgStr.append(subMsg);

    //subMsg = msgStr.substr(270,4);
    //replyMsgStr = replyMsgStr.append(subMsg);

    //subMsg = msgStr.substr(318,42);
    //replyMsgStr = replyMsgStr.append(subMsg);

    subMsg = msgStr.substr(316, 46); //changed from 336 to 316 due to the reversal issue,,,,not it should be fixed. 
    replyMsgStr = replyMsgStr.append(subMsg);

    // Get message length
    int length = replyMsgStr.length();
    length = length / 2;
    string msgLength = intToHex(length);
    replyMsgStr = msgLength.append(replyMsgStr);

    message.setReplyMessage(replyMsgStr);
}

}

1 个答案:

答案 0 :(得分:2)

if (sendLogoff)代码中,您似乎创建了logoffMessage,但发送了logonMessage。此外,如果消息是动态分配的,我看不到你试图在任何地方解除分配。

我对replyMessage的内存分配和释放有类似的担忧。

我无法了解messageHandler的作用。

如果您写入不再与其对等方连接的套接字,程序将收到SIGPIPE。如果您没有实现信号处理程序来处理它,您的程序将终止。如果您使用send代替write,则可以传递MSG_NOSIGNAL标记以取消SIGPIPEsend将返回EPIPE而是错误信息。

由于你将套接字设置为非阻塞,你应该注意Loki Astari关于简短读写的警告,以及他处理它们的建议。

由于命令是从cron作业启动的,我建议您查看是否通过电子邮件向您发送了该程序的输出。如果在系统上禁用了输出的电子邮件,请修改cron作业条目以将输出重定向到您可以检查的日志文件。使用bash,您可以使用&>重定向执行此操作。如,

$ command &> /tmp/command.log