<commit_before>/*
  +----------------------------------------------------------------------+
  | Swoole                                                               |
  +----------------------------------------------------------------------+
  | This source file is subject to version 2.0 of the Apache license,    |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.apache.org/licenses/LICENSE-2.0.html                      |
  | If you did not receive a copy of the Apache2.0 license and are unable|
  | to obtain it through the world-wide-web, please send a note to       |
  | <EMAIL> so we can mail you a copy immediately.            |
  +----------------------------------------------------------------------+
  | Author: <NAME>  <<EMAIL>>                        |
  +----------------------------------------------------------------------+
*/

#include "php_swoole.h"

#ifdef HAVE_PTRACE
#include <stddef.h>
#include <sys/ptrace.h>

#if SIZEOF_LONG == 4
#define PTR_FMT "08"
#elif SIZEOF_LONG == 8
#define PTR_FMT "016"
#endif

#if defined(PT_ATTACH) && !defined(PTRACE_ATTACH)
#if __APPLE__
#define PTRACE_ATTACH PT_ATTACHEXC
#else
#define PTRACE_ATTACH PT_ATTACH
#endif
#endif

#if defined(PT_DETACH) && !defined(PTRACE_DETACH)
#define PTRACE_DETACH PT_DETACH
#endif

#if defined(PT_READ_D) && !defined(PTRACE_PEEKDATA)
#define PTRACE_PEEKDATA PT_READ_D
#endif

#define valid_ptr(p) ((p) && 0 == ((p) & (sizeof(long) - 1)))

static void trace_request(swWorker *worker);
static int trace_dump(swWorker *worker, FILE *slowlog);
static int trace_get_long(pid_t traced_pid, long addr, long *data);
static int trace_get_strz(pid_t traced_pid, char *buf, size_t sz, long addr);

static void trace_request(swWorker *worker)
{
    FILE *slowlog = SwooleG.serv->request_slowlog_file;
    pid_t traced_pid = worker->pid;
    int ret = trace_dump(worker, slowlog);
    if (ret < 0)
    {
        swSysError("failed to trace worker %d, error lint =%d.", worker->pid, -ret);
    }
    if (0 > ptrace(PTRACE_DETACH, traced_pid, (void *) 1, 0))
    {
        swSysError("failed to ptrace(DETACH) worker %d", worker->pid);
    }
    fflush(slowlog);
}

void php_swoole_trace_check(swServer *serv)
{
    uint8_t timeout = serv->request_slowlog_timeout;
    int count = serv->worker_num + SwooleG.task_worker_num;
    int i = serv->trace_event_worker ? 0 : serv->worker_num;
    swWorker *worker;

    for (; i < count; i++)
    {
        worker = swServer_get_worker(serv, i);
        swTraceLog(SW_TRACE_SERVER, "trace request, worker#%d, pid=%d. request_time=%d.", i, worker->pid, worker->request_time);
        if (!(worker->request_time > 0 && worker->traced == 0 && SwooleGS->now - worker->request_time >= timeout))
        {
            continue;
        }
        swWarn("PTRACE_ATTACH worker%d, pid=%d\n", i,  worker->pid);
        if (ptrace(PTRACE_ATTACH, worker->pid, 0, 0) < 0)
        {
            swSysError("failed to ptrace(ATTACH, %d) worker#%d,", worker->pid, worker->id);
            continue;
        }
        worker->tracer = trace_request;
        worker->traced = 1;
    }
}

static int trace_get_long(pid_t traced_pid, long addr, long *data)
{
    errno = 0;
    *data = ptrace(PTRACE_PEEKDATA, traced_pid, (void *) addr, 0);
    if (*data < 0)
    {
        return -1;
    }
    return 0;
}

static int trace_get_strz(pid_t traced_pid, char *buf, size_t sz, long addr)
{
    int i;
    long l = addr;
    char *lc = (char *) &l;

    i = l % SIZEOF_LONG;
    l -= i;
    for (addr = l;; addr += SIZEOF_LONG)<commit_msg>remove debug info<commit_after>/*
  +----------------------------------------------------------------------+
  | Swoole                                                               |
  +----------------------------------------------------------------------+
  | This source file is subject to version 2.0 of the Apache license,    |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.apache.org/licenses/LICENSE-2.0.html                      |
  | If you did not receive a copy of the Apache2.0 license and are unable|
  | to obtain it through the world-wide-web, please send a note to       |
  | <EMAIL> so we can mail you a copy immediately.            |
  +----------------------------------------------------------------------+
  | Author: <NAME>  <<EMAIL>>                        |
  +----------------------------------------------------------------------+
*/

#include "php_swoole.h"

#ifdef HAVE_PTRACE
#include <stddef.h>
#include <sys/ptrace.h>

#if SIZEOF_LONG == 4
#define PTR_FMT "08"
#elif SIZEOF_LONG == 8
#define PTR_FMT "016"
#endif

#if defined(PT_ATTACH) && !defined(PTRACE_ATTACH)
#if __APPLE__
#define PTRACE_ATTACH PT_ATTACHEXC
#else
#define PTRACE_ATTACH PT_ATTACH
#endif
#endif

#if defined(PT_DETACH) && !defined(PTRACE_DETACH)
#define PTRACE_DETACH PT_DETACH
#endif

#if defined(PT_READ_D) && !defined(PTRACE_PEEKDATA)
#define PTRACE_PEEKDATA PT_READ_D
#endif

#define valid_ptr(p) ((p) && 0 == ((p) & (sizeof(long) - 1)))

static void trace_request(swWorker *worker);
static int trace_dump(swWorker *worker, FILE *slowlog);
static int trace_get_long(pid_t traced_pid, long addr, long *data);
static int trace_get_strz(pid_t traced_pid, char *buf, size_t sz, long addr);

static void trace_request(swWorker *worker)
{
    FILE *slowlog = SwooleG.serv->request_slowlog_file;
    pid_t traced_pid = worker->pid;
    int ret = trace_dump(worker, slowlog);
    if (ret < 0)
    {
        swSysError("failed to trace worker %d, error lint =%d.", worker->pid, -ret);
    }
    if (0 > ptrace(PTRACE_DETACH, traced_pid, (void *) 1, 0))
    {
        swSysError("failed to ptrace(DETACH) worker %d", worker->pid);
    }
    fflush(slowlog);
}

void php_swoole_trace_check(swServer *serv)
{
    uint8_t timeout = serv->request_slowlog_timeout;
    int count = serv->worker_num + SwooleG.task_worker_num;
    int i = serv->trace_event_worker ? 0 : serv->worker_num;
    swWorker *worker;

    for (; i < count; i++)
    {
        worker = swServer_get_worker(serv, i);
        swTraceLog(SW_TRACE_SERVER, "trace request, worker#%d, pid=%d. request_time=%d.", i, worker->pid, worker->request_time);
        if (!(worker->request_time > 0 && worker->traced == 0 && SwooleGS->now - worker->request_time >= timeout))
        {
            continue;
        }
        if (ptrace(PTRACE_ATTACH, worker->pid, 0, 0) < 0)
        {
            swSysError("failed to ptrace(ATTACH, %d) worker#%d,", worker->pid, worker->id);
            continue;
        }
        worker->tracer = trace_request;
        worker->traced = 1;
    }
}

static int trace_get_long(pid_t traced_pid, long addr, long *data)
{
    errno = 0;
    *data = ptrace(PTRACE_PEEKDATA, traced_pid, (void *) addr, 0);
    if (*data < 0)
    {
        return -1;
    }
    return 0;
}

static int trace_get_strz(pid_t traced_pid, char *buf, size_t sz, long addr)
{
    int i;
    long l = addr;
    char *lc = (char *) &l;

    i = l % SIZEOF_LONG;
    l -= i;
    for (addr = l;; addr += SIZEOF_LONG)
{'fraction_non_alphanumeric': 0.19555310040049717, 'fraction_numerical': 0.008838558210191963, 'mean_word_length': 2.08301404853129, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 60, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1147818', 'n_tokens_mistral': 2452, 'n_tokens_neox': 2347, 'n_words': 624}