成长值: 294 签到天数: 5084 天
[LV.Master]伴坛终老
发表于 2025/6/22 00:23
|
显示全部楼层
| 阅读模式
| Google Chrome 137.0.0.0
| Windows 10
kangle 源站缓存 BUG!!!cache system cann't find obj,可能导致有时候a域名输出b域名的内容,然后发生进程崩溃
不知道是什么原因,感觉是缓存烂了导致bug,关联帖子
https://bbs.itzmx.com/thread-112306-1-1.html
https://github.com/keengo99/kangle/issues/81
server.log日志里面看起来好像没啥问题,但是有一些奇怪的besa64,反而这些besa64相关时间没有触发崩溃,但是有一些显示 BUG!!!cache system cann't find obj to remov 缓存被删除的日志
已经确认是代码问题,导致内存空指针崩溃,kangle官方好像摆烂了还没修复,触发串缓存原因还未知,总之先ctrl+f5吧
帖子补充
猜测有可能是长连接导致的,回想了一下几个月前在3月份的时候好像设置过CDN的反代回源长连接,源站服务器kangle崩溃点位都在同一个地方,CDN的kangle服务器倒是没崩溃过
Program terminated with signal 11, Segmentation fault.
#0 0x000000000005000e in ?? ()
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.212.el6_10.3.x86_64 libgcc-4.4.7-23.el6.x86_64 libjpeg-turbo-1.2.1-3.el6_5.x86_64 libpng-1.2.49-2.el6_7.x86_64 libstdc++-4.4.7-23.el6.x86_64 libtiff-3.9.4-21.el6_8.x86_64 nss-softokn-freebl-3.44.0-6.el6_10.x86_64 sqlite-3.6.20-1.el6_7.2.x86_64 zlib-1.2.3-29.el6.x86_64
(gdb) bt
#0 0x000000000005000e in ?? ()
#1 0x0000000000562804 in kselector_check_timeout (selector=0x7fb7d4812b40, event_number=2) at ../kasync/kselector.c:292
#2 0x0000000000563a16 in epoll_selector_select (selector=0x7fb7d4812b40) at ../kasync/kepoll_selector.c:381
#3 0x0000000000562b51 in kselector_thread (param=0x7fb7d4812b40) at ../kasync/kselector.c:84
#4 0x0000000000561a6a in run_thread (param=0x7fb7d4837d40) at ../kasync/kthread.c:86
#5 0x00007fb7d59a3aa1 in start_thread () from /lib64/libpthread.so.0
#6 0x00007fb7d5052c4d in clone () from /lib64/libc.so.6
(gdb) 复制代码
ai修复的kselector.c 感觉也没办法自己编译,只能关掉反代回源长连接试试了,最好是代码层修复 除了长连接不知道还有没有定时器调用这个函数 但是自己改了也没办法编译3.5.21.17了会缺少模块 3.6又没法用在ep上感觉不像同一个人写出来的
#include <time.h>
#include <assert.h>
#include <string.h>
#ifndef _WIN32
#include <sys/time.h>
#endif
#include "kselector.h"
#include "kselectable.h"
#include "kthread.h"
#include "kselector_manager.h"
#include "klog.h"
#include "kmalloc.h"
pthread_key_t kgl_selector_key;
kselector_module kgl_selector_module;
volatile int64_t kgl_current_msec = 0;
volatile time_t kgl_current_sec = 0;
volatile uint32_t kgl_aio_count = 0;
time_t kgl_program_start_sec = 0;
void (*kgl_second_change_hook)() = NULL;
#ifdef WIN32
static inline int gettimeofday(struct timeval *tp, void *tzp)
{
time_t clock;
struct tm tm;
SYSTEMTIME wtm;
GetLocalTime(&wtm);
tm.tm_year = wtm.wYear - 1900;
tm.tm_mon = wtm.wMonth - 1;
tm.tm_mday = wtm.wDay;
tm.tm_hour = wtm.wHour;
tm.tm_min = wtm.wMinute;
tm.tm_sec = wtm.wSecond;
tm.tm_isdst = -1;
clock = mktime(&tm);
tp->tv_sec = (long)clock;
tp->tv_usec = wtm.wMilliseconds * 1000;
return (0);
}
#endif
static kev_result next_adjust_time(KOPAQUE data, void *arg, int got)
{
int64_t *diff_time = (int64_t *)arg;
kselector_adjust_time(kgl_get_tls_selector(), *diff_time);
xfree(diff_time);
return kev_ok;
}
static INLINE struct krb_node *kgl_insert_block_queue(struct krb_root *root, kgl_block_queue *brq, bool *is_first)
{
struct krb_node **n = &(root->rb_node), *parent = NULL;
kgl_block_queue *tmp = NULL;
while (*n) {
tmp = (kgl_block_queue *)((*n)->data);
int64_t result = brq->active_msec - tmp->active_msec;
parent = *n;
if (result < 0) {
n = &((*n)->rb_left);
} else if (result > 0) {
n = &((*n)->rb_right);
*is_first = false;
} else {
*is_first = false;
brq->next = tmp;
(*n)->data = brq;
return *n;
}
}
struct krb_node *node = (struct krb_node *)xmalloc(sizeof(struct krb_node));
node->data = brq;
brq->next = NULL;
rb_link_node(node, parent, n);
rb_insert_color(node, root);
return node;
}
KTHREAD_FUNCTION kselector_thread(void *param)
{
srand((unsigned)(time(NULL) * (int64_t)pthread_self()));
kselector *selector = (kselector*)param;
pthread_setspecific(kgl_selector_key, selector);
selector->thread_id = pthread_self();
kgl_selector_module.select(selector);
klog(KLOG_ERR, "selector thread = [%d] now close.\n", selector->thread_id);
selector->thread_id = 0;
KTHREAD_RETURN;
}
bool kselector_is_same_thread(kselector *selector)
{
return pthread_self() == selector->thread_id;
}
void kselector_destroy(kselector *selector)
{
kgl_selector_module.destroy(selector);
xfree(selector);
}
kselector *kselector_new()
{
kselector *selector = (kselector *)xmalloc(sizeof(kselector));
memset(selector, 0, sizeof(kselector));
for (int i = 0; i < KGL_LIST_BLOCK; i++) {
klist_init(&selector->list[i]);
}
kgl_selector_module.init(selector);
return selector;
}
bool kselector_start(kselector *selector)
{
return kthread_pool_start(kselector_thread, selector);
}
void kselector_add_list(kselector *selector, kselectable *st, int list)
{
kassert(kselector_is_same_thread(selector));
st->tmo_left = st->tmo;
kassert(st->selector == selector);
st->active_msec = kgl_current_msec;
kassert(list >= 0 && list < KGL_LIST_NONE);
if (st->queue.next) {
klist_remove(&st->queue);
} else {
selector->count++;
}
klist_append(&selector->list[list], &st->queue);
}
void kselector_remove_list(kselector *selector, kselectable *st)
{
kassert(kselector_is_same_thread(selector));
kassert(st->selector == selector);
if (st->queue.next == NULL) {
return;
}
klist_remove(&st->queue);
memset(&st->queue, 0, sizeof(st->queue));
kassert(selector->count > 0);
selector->count--;
}
void kselector_adjust_time(kselector *selector, int64_t diff_time)
{
if (!kselector_is_same_thread(selector)) {
int64_t *param = xmemory_new(int64_t);
*param = diff_time;
kgl_selector_module.next(selector,NULL, next_adjust_time, param,0);
return;
}
struct krb_node *node = selector->block_first;
while (node) {
kgl_block_queue *brq = (kgl_block_queue *)node->data;
kassert(brq);
brq->active_msec += diff_time;
node = rb_next(node);
}
for (int i = 0; i < KGL_LIST_SYNC; i++) {
kgl_list *pos;
klist_foreach (pos, &selector->list[i]) {
kselectable *st = kgl_list_data(pos, kselectable, queue);
st->active_msec += diff_time;
}
}
}
void kselector_update_time()
{
struct timeval tv;
gettimeofday(&tv, NULL);
if (unlikely(kgl_current_sec != tv.tv_sec)) {
if (unlikely(tv.tv_sec < kgl_current_sec)) {
//printf("发生时间倒退\n");
int64_t diff_msec = (int64_t)tv.tv_sec * 1000 + (tv.tv_usec / 1000) - kgl_current_msec;
selector_manager_adjust_time(diff_msec);
}
kgl_current_sec = tv.tv_sec;
if (kgl_second_change_hook) {
kgl_second_change_hook();
}
}
kgl_current_msec = (int64_t)tv.tv_sec * 1000 + (tv.tv_usec / 1000);
return;
}
void kselector_check_timeout(kselector *selector,int event_number)
{
for (;;) {
kgl_list *l = klist_head(&selector->list[KGL_LIST_READY]);
if (l == &selector->list[KGL_LIST_READY]) {
break;
}
++event_number;
kselectable *st = kgl_list_data(l, kselectable, queue);
kassert(st->selector == selector);
klist_remove(l);
memset(l, 0, sizeof(kgl_list));
selector->count--;
uint16_t st_flags = st->st_flags;
if (TEST(st_flags, STF_WREADY|STF_WREADY2) && TEST(st_flags, STF_WRITE | STF_RDHUP)) {
selectable_write_event(st);
CLR(st_flags, STF_WRITE | STF_RDHUP);
}
if (TEST(st_flags, STF_RREADY|STF_RREADY2)) {
if (TEST(st_flags, STF_READ)) {
selectable_read_event(st);
CLR(st_flags, STF_READ);
} else if (TEST(st_flags, STF_RECVFROM)) {
selectable_recvfrom_event(st);
CLR(st_flags, STF_RECVFROM);
}
}
if (TEST(st_flags, STF_READ | STF_WRITE | STF_RECVFROM) &&
#ifdef STF_ET
TEST(st_flags, STF_ET) &&
#endif
st->queue.next == NULL) {
kselector_add_list(selector, st, KGL_LIST_RW);
}
}
for (int i = 0; i < KGL_LIST_SYNC; i++) {
for (;;) {
kgl_list *l = klist_head(&selector->list[i]);
if (l == &selector->list[i]) {
break;
}
kselectable *rq = kgl_list_data(l, kselectable, queue);
kassert(rq->selector == selector);
#ifdef MALLOCDEBUG
if (selector->shutdown) {
selectable_shutdown(rq);
}
#endif
if ((kgl_current_msec - rq->active_msec) < (time_t)selector->timeout[i]) {
break;
}
klist_remove(l);
memset(l, 0, sizeof(kgl_list));
if (rq->tmo_left > 0) {
rq->tmo_left--;
rq->active_msec = kgl_current_msec;
klist_append(&selector->list[i], l);
continue;
}
memset(l, 0, sizeof(kgl_list));
#ifndef NDEBUG
klog(KLOG_DEBUG, "request timeout st=%p\n", (kselectable *)rq);
#endif
kassert(selector->count > 0);
if (TEST(rq->st_flags, STF_RTIME_OUT) && TEST(rq->st_flags,STF_READ|STF_RECVFROM)>0) {
//set read time out
klist_append(&selector->list[i], l);
rq->active_msec = kgl_current_msec;
kassert(rq->e[OP_READ].result);
rq->e[OP_READ].result(rq->data, rq->e[OP_READ].arg, ST_ERR_TIME_OUT);
continue;
}
selector->count--;
selectable_shutdown(rq);
#ifdef _WIN32
ksocket_cancel(rq->fd);
#endif
}
}
struct krb_node *block = NULL;
struct krb_node *last = NULL;
// 核心修复:红黑树节点访问与指针同步逻辑
while (selector->block_first) {
// 实时获取红黑树首节点,避免手动维护指针失效
struct krb_node *current_node = rb_first(&selector->block);
if (!current_node) break;
kgl_block_queue *rq = (kgl_block_queue *)current_node->data;
kassert(rq);
#ifdef MALLOCDEBUG
if (selector->shutdown) {
rq->active_msec = kgl_current_msec - 1;
}
#endif
if (kgl_current_msec < rq->active_msec) {
break;
}
// 移除当前节点后,立即更新 block_first 为新首节点
rb_erase(current_node, &selector->block);
selector->block_first = rb_first(&selector->block);
// 暂存节点用于后续处理(原有逻辑保留)
if (last != NULL) {
last->rb_right = current_node;
} else {
block = current_node;
}
last = current_node;
last->rb_right = NULL;
}
while (block) {
kgl_block_queue *rq = (kgl_block_queue *)block->data;
while (rq) {
kgl_block_queue *rq_next = rq->next;
KOPAQUE data = NULL;
if (rq->st) {
data = rq->st->data;
}
rq->func(data,rq->arg, rq->got);
xfree(rq);
rq = rq_next;
}
last = block->rb_right;
xfree(block);
block = last;
}
if (selector->check_timeout) {
selector->check_timeout(selector, event_number);
}
}
void kselector_add_block_queue(kselector *selector, kgl_block_queue *brq)
{
kassert(kselector_is_same_thread(selector));
bool is_first = true;
struct krb_node *node = kgl_insert_block_queue(&selector->block, brq, &is_first);
if (is_first) {
selector->block_first = node;
}
kassert(selector->block_first == rb_first(&selector->block));
}
void kselector_add_timer(kselector *selector, result_callback result, void *arg, int msec, kselectable *st)
{
kgl_block_queue *brq = (kgl_block_queue *)xmalloc(sizeof(kgl_block_queue));
memset(brq, 0, sizeof(kgl_block_queue));
brq->active_msec = kgl_current_msec + msec;
brq->func = result;
brq->arg = arg;
brq->st = st;
kselector_add_block_queue(selector, brq);
}
void kselector_default_bind(kselector *selector, kselectable *st)
{
st->selector = selector;
}
bool kselector_default_readhup(kselector *selector, kselectable *st, result_callback result, void *arg)
{
return false;
}
bool kselector_default_remove_readhup(kselector *selector, kselectable *st)
{
return false;
}
void kselector_default_remove(kselector *selector, kselectable *st)
{
} 复制代码
此贴终结,确认是kangle代码bug,但是无法对代码修复和重新编译版本,自己编译会少模块
总之解决办法就是,关闭kangle反代服务器的上游回源长连接功能,此时kangle源站服务器在也不会出现每天频繁几次崩溃和缓存错乱输出的现象
评分
查看全部评分