LLM4Binary/decompile-bench-makefile huggingface dataset:
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: nodeUpdateAddressIfNeeded
int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, int port) {
    char ip[REDIS_IP_STR_LEN];

    /* We don't proceed if the link is the same as the sender link, as this
     * function is designed to see if the node link is consistent with the
     * symmetric link that is used to receive PINGs from the node.
     *
     * As a side effect this function never frees the passed 'link', so
     * it is safe to call during packet processing. */
    // 连接不变，直接返回
    if (link == node->link) return 0;

    // 获取字符串格式的 ip 地址
    nodeIp2String(ip,link);
    // 获取端口号
    if (node->port == port && strcmp(ip,node->ip) == 0) return 0;

    /* IP / port is different, update it. */
    memcpy(node->ip,ip,sizeof(ip));
    node->port = port;

    // 释放旧连接（新连接会在之后自动创建）
    if (node->link) freeClusterLink(node->link);

    redisLog(REDIS_WARNING,"Address updated for node %.40s, now %s:%d",
        node->name, node->ip, node->port);

    /* Check if this is our master and we have to change the
     * replication target as well. */
    // 如果连接来自当前节点（从节点）的主节点，那么根据新地址设置复制对象
    if (nodeIsSlave(myself) && myself->slaveof == node)
        replicationSetMaster(node->ip, node->port);
    return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x38, %rsp
cmpq %rsi, 0x8c0(%rdi)
je 0x518dd
movl %edx, %ebp
movq %rdi, %rbx
movl 0x8(%rsi), %edi
xorl %r14d, %r14d
movq %rsp, %rsi
movl $0x2e, %edx
xorl %ecx, %ecx
callq 0x21ee7
cmpl %ebp, 0x8b8(%rbx)
jne 0x5184d
leaq 0x888(%rbx), %rsi
movq %rsp, %rdi
callq 0x1f880
testl %eax, %eax
je 0x518e0
leaq 0x888(%rbx), %r15
movups 0x1e(%rsp), %xmm0
movups %xmm0, 0x8a6(%rbx)
movaps (%rsp), %xmm0
movaps 0x10(%rsp), %xmm1
movups %xmm1, 0x898(%rbx)
movups %xmm0, 0x888(%rbx)
movl %ebp, 0x8b8(%rbx)
movq 0x8c0(%rbx), %rdi
testq %rdi, %rdi
je 0x51894
callq 0x50a5c
movl 0x8b8(%rbx), %ebp
leaq 0x8(%rbx), %rdx
leaq 0x4a96f(%rip), %rsi     # 0x9c20e
movl $0x3, %edi
movq %r15, %rcx
movl %ebp, %r8d
xorl %eax, %eax
callq 0x23223
movq 0x8cd70(%rip), %rax     # 0xde628
movl $0x1, %r14d
testb $0x2, 0x30(%rax)
je 0x518e0
cmpq %rbx, 0x850(%rax)
jne 0x518e0
movl 0x8b8(%rbx), %esi
movq %r15, %rdi
callq 0x35767
jmp 0x518e0
xorl %r14d, %r14d
movl %r14d, %eax
addq $0x38, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterSetMaster
void clusterSetMaster(clusterNode *n) {
    redisAssert(n != myself);
    redisAssert(myself->numslots == 0);

    if (nodeIsMaster(myself)) {
        myself->flags &= ~REDIS_NODE_MASTER;
        myself->flags |= REDIS_NODE_SLAVE;
        clusterCloseAllSlots();
    } else {
        if (myself->slaveof)
            clusterNodeRemoveSlave(myself->slaveof,myself);
    }

    // 将 slaveof 属性指向主节点
    myself->slaveof = n;

    // 设置主节点的 IP 和地址，开始对它进行复制
    clusterNodeAddSlave(n,myself);
    replicationSetMaster(n->ip, n->port);
    resetManualFailover();
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq 0x8cb70(%rip), %r14     # 0xde628
cmpq %rdi, %r14
je 0x51ba4
cmpl $0x0, 0x840(%r14)
jne 0x51bb9
movq %rdi, %rbx
movl 0x30(%r14), %eax
testb $0x1, %al
jne 0x51b0b
movq 0x850(%r14), %r15
testq %r15, %r15
je 0x51b4b
movslq 0x844(%r15), %rax
testq %rax, %rax
jle 0x51b4b
movq 0x848(%r15), %rdx
xorl %ecx, %ecx
cmpq %r14, (%rdx,%rcx,8)
je 0x51b7c
incq %rcx
cmpq %rcx, %rax
jne 0x51afb
jmp 0x51b4b
andl $-0x4, %eax
orl $0x2, %eax
movl %eax, 0x30(%r14)
leaq 0x7848c(%rip), %r15     # 0xc9fa8
movq 0x7d0(%r15), %rdi
addq $0x28, %rdi
movl $0x20000, %edx          # imm = 0x20000
xorl %esi, %esi
callq 0x1f110
movl $0x20028, %edi          # imm = 0x20028
addq 0x7d0(%r15), %rdi
movl $0x20000, %edx          # imm = 0x20000
xorl %esi, %esi
callq 0x1f110
movq %rbx, 0x850(%r14)
movq %rbx, %rdi
movq %r14, %rsi
callq 0x4ff2d
movl 0x8b8(%rbx), %esi
addq $0x888, %rbx            # imm = 0x888
movq %rbx, %rdi
callq 0x35767
popq %rbx
popq %r14
popq %r15
jmp 0x50620
leaq (%rdx,%rcx,8), %rdi
leaq (%rdx,%rcx,8), %rsi
addq $0x8, %rsi
notl %ecx
addl %eax, %ecx
movslq %ecx, %rdx
callq 0x1f780
decl 0x844(%r15)
movq 0x8ca86(%rip), %r14     # 0xde628
jmp 0x51b4b
leaq 0x4ad07(%rip), %rdi     # 0x9c8b2
leaq 0x4a10b(%rip), %rsi     # 0x9bcbd
movl $0x109a, %edx           # imm = 0x109A
jmp 0x51bcc
leaq 0x4acfe(%rip), %rdi     # 0x9c8be
leaq 0x4a0f6(%rip), %rsi     # 0x9bcbd
movl $0x109b, %edx           # imm = 0x109B
callq 0x4ca32
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterHandleConfigEpochCollision
void clusterHandleConfigEpochCollision(clusterNode *sender) {
    /* Prerequisites: nodes have the same configEpoch and are both masters. */
    if (sender->configEpoch != myself->configEpoch ||
        !nodeIsMaster(sender) || !nodeIsMaster(myself)) return;
    /* Don't act if the colliding node has a smaller Node ID. */
    if (memcmp(sender->name,myself->name,REDIS_CLUSTER_NAMELEN) <= 0) return;
    /* Get the next ID available at the best of this node knowledge. */
    server.cluster->currentEpoch++;
    myself->configEpoch = server.cluster->currentEpoch;
    clusterSaveConfigOrDie(1);
    redisLog(REDIS_VERBOSE,
        "WARNING: configEpoch collision with node %.40s."
        " Updating my configEpoch to %llu",
        sender->name,
        (unsigned long long) myself->configEpoch);
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq 0x38(%rdi), %rax
movq 0x8ca3e(%rip), %r14     # 0xde628
cmpq 0x38(%r14), %rax
jne 0x51c19
movq %rdi, %rbx
testb $0x1, 0x30(%rdi)
je 0x51c19
testb $0x1, 0x30(%r14)
je 0x51c19
addq $0x8, %rbx
leaq 0x8(%r14), %rsi
movl $0x28, %edx
movq %rbx, %rdi
callq 0x1f940
testl %eax, %eax
jg 0x51c21
addq $0x8, %rsp
popq %rbx
popq %r14
retq
leaq 0x78380(%rip), %rax     # 0xc9fa8
movq 0x7d0(%rax), %rax
movq 0x8(%rax), %rcx
incq %rcx
movq %rcx, 0x8(%rax)
movq %rcx, 0x38(%r14)
movl $0x1, %edi
callq 0x501ce
movq 0x8c9d9(%rip), %rax     # 0xde628
movq 0x38(%rax), %rcx
leaq 0x4a650(%rip), %rsi     # 0x9c2aa
movl $0x1, %edi
movq %rbx, %rdx
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0x23223
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterDelNodeSlots
int clusterDelNodeSlots(clusterNode *node) {
    int deleted = 0, j;

    for (j = 0; j < REDIS_CLUSTER_SLOTS; j++) {
        // 如果这个槽由该节点负责，那么删除它
        if (clusterNodeGetSlotBit(node,j)) clusterDelSlot(j);
        deleted++;
    }
    return deleted;
}

// Assembly:
pushq %rbp
pushq %rbx
pushq %rax
movq %rdi, %rbx
xorl %ebp, %ebp
movl %ebp, %eax
shrl $0x3, %eax
movzbl 0x40(%rbx,%rax), %eax
movl %ebp, %ecx
andl $0x7, %ecx
btl %ecx, %eax
jae 0x5281e
movl %ebp, %edi
callq 0x5085d
incl %ebp
cmpl $0x4000, %ebp           # imm = 0x4000
jne 0x52803
movl $0x4000, %eax           # imm = 0x4000
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterWriteHandler
void clusterWriteHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
    clusterLink *link = (clusterLink*) privdata;
    ssize_t nwritten;
    REDIS_NOTUSED(el);
    REDIS_NOTUSED(mask);

    // 写入信息
    nwritten = write(fd, link->sndbuf, sdslen(link->sndbuf));

    // 写入错误
    if (nwritten <= 0) {
        redisLog(REDIS_DEBUG,"I/O error writing to node link: %s",
            strerror(errno));
        handleLinkIOError(link);
        return;
    }

    // 删除已写入的部分
    sdsrange(link->sndbuf,nwritten,-1);

    // 如果所有当前节点输出缓冲区里面的所有内容都已经写入完毕
    // （缓冲区为空）
    // 那么删除写事件处理器
    if (sdslen(link->sndbuf) == 0)
        aeDeleteFileEvent(server.el, link->fd, AE_WRITABLE);
}

// Assembly:
pushq %rbx
movq %rdx, %rbx
movl %esi, %edi
movq 0x10(%rdx), %rsi
movslq -0x8(%rsi), %rdx
callq 0x1fb30
testq %rax, %rax
jle 0x52a3b
movq 0x10(%rbx), %rdi
movl %eax, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x28f3c
movq 0x10(%rbx), %rax
cmpl $0x0, -0x8(%rax)
je 0x52a63
popq %rbx
retq
callq 0x1f810
movl (%rax), %edi
callq 0x1f630
leaq 0x49ae1(%rip), %rsi     # 0x9c52f
xorl %edi, %edi
movq %rax, %rdx
xorl %eax, %eax
callq 0x23223
movq %rbx, %rdi
popq %rbx
jmp 0x50a5c
leaq 0x7753e(%rip), %rax     # 0xc9fa8
movq 0x28(%rax), %rdi
movl 0x8(%rbx), %esi
movl $0x2, %edx
popq %rbx
jmp 0x20ce8
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterBroadcastMessage
void clusterBroadcastMessage(void *buf, size_t len) {
    dictIterator *di;
    dictEntry *de;

    // 遍历所有已知节点
    di = dictGetSafeIterator(server.cluster->nodes);
    while((de = dictNext(di)) != NULL) {
        clusterNode *node = dictGetVal(de);

        // 不向未连接节点发送信息
        if (!node->link) continue;

        // 不向节点自身或者 HANDSHAKE 状态的节点发送信息
        if (node->flags & (REDIS_NODE_MYSELF|REDIS_NODE_HANDSHAKE))
            continue;

        // 发送信息
        clusterSendMessage(node->link,buf,len);
    }
    dictReleaseIterator(di);
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x774ad(%rip), %rax     # 0xc9fa8
movq 0x7d0(%rax), %rax
movq 0x18(%rax), %rdi
callq 0x22aa0
movq %rax, %r15
movq %rax, %rdi
callq 0x22acf
testq %rax, %rax
je 0x52b41
movq 0x8(%rax), %rax
movq 0x8c0(%rax), %rdi
testq %rdi, %rdi
je 0x52b3c
testb $0x30, 0x30(%rax)
jne 0x52b3c
movq %r14, %rsi
movq %rbx, %rdx
callq 0x52a7c
movq %r15, %rdi
jmp 0x52b11
movq %r15, %rdi
popq %rbx
popq %r14
popq %r15
jmp 0x22b86
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterHandleManualFailover
void clusterHandleManualFailover(void) {
    /* Return ASAP if no manual failover is in progress. */
    if (server.cluster->mf_end == 0) return;

    /* If mf_can_start is non-zero, the failover was alrady triggered so the
     * next steps are performed by clusterHandleSlaveFailover(). */
    if (server.cluster->mf_can_start) return;

    if (server.cluster->mf_master_offset == 0) return; /* Wait for offset... */

    if (server.cluster->mf_master_offset == replicationGetSlaveOffset()) {
        /* Our replication offset matches the master replication offset
         * announced after clients were paused. We can start the failover. */
        server.cluster->mf_can_start = 1;
        redisLog(REDIS_WARNING,
            "All master replication stream processed, "
            "manual failover can start.");
    }
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
leaq 0x76844(%rip), %rbx     # 0xc9fa8
movq 0x7d0(%rbx), %rax
cmpq $0x0, 0x60050(%rax)
je 0x5377e
cmpl $0x0, 0x60068(%rax)
je 0x53786
addq $0x8, %rsp
popq %rbx
popq %r14
retq
movq 0x60060(%rax), %r14
testq %r14, %r14
je 0x5377e
callq 0x35de0
cmpq %rax, %r14
jne 0x5377e
movq 0x7d0(%rbx), %rax
movl $0x1, 0x60068(%rax)
leaq 0x48f45(%rip), %rsi     # 0x9c6f9
movl $0x3, %edi
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0x23223
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: createDumpPayload
void createDumpPayload(rio *payload, robj *o) {
    unsigned char buf[2];
    uint64_t crc;

    /* Serialize the object in a RDB-like format. It consist of an object type
     * byte followed by the serialized object. This is understood by RESTORE. */
    // 将对象序列化为一个 RDB 格式对象
    // 序列化对象以对象类型为首，后跟序列化后的对象
    // 如图
    //
    // |<-- RDB payload  -->|
    //      序列化数据
    // +-------------+------+
    // | 1 byte type | obj  |
    // +-------------+------+
    rioInitWithBuffer(payload,sdsempty());
    redisAssert(rdbSaveObjectType(payload,o));
    redisAssert(rdbSaveObject(payload,o));

    /* Write the footer, this is how it looks like:
     * ----------------+---------------------+---------------+
     * ... RDB payload | 2 bytes RDB version | 8 bytes CRC64 |
     * ----------------+---------------------+---------------+
     * RDB version and CRC are both in little endian.
     */

    /* RDB version */
    // 写入 RDB 版本
    buf[0] = REDIS_RDB_VERSION & 0xff;
    buf[1] = (REDIS_RDB_VERSION >> 8) & 0xff;
    payload->io.buffer.ptr = sdscatlen(payload->io.buffer.ptr,buf,2);

    /* CRC64 */
    // 写入 CRC 校验和
    crc = crc64(0,(unsigned char*)payload->io.buffer.ptr,
                sdslen(payload->io.buffer.ptr));
    memrev64ifbe(&crc);
    payload->io.buffer.ptr = sdscatlen(payload->io.buffer.ptr,&crc,8);

    // 整个数据的结构:
    //
    // | <--- 序列化数据 -->|
    // +-------------+------+---------------------+---------------+
    // | 1 byte type | obj  | 2 bytes RDB version | 8 bytes CRC64 |
    // +-------------+------+---------------------+---------------+

}

// Assembly:
pushq %r14
pushq %rbx
subq $0x18, %rsp
movq %rsi, %r14
movq %rdi, %rbx
callq 0x2845e
movq %rbx, %rdi
movq %rax, %rsi
callq 0x588b3
movq %rbx, %rdi
movq %r14, %rsi
callq 0x36ede
testl %eax, %eax
je 0x55083
movq %rbx, %rdi
movq %r14, %rsi
callq 0x37055
testl %eax, %eax
je 0x55098
leaq 0xe(%rsp), %rsi
movw $0x6, (%rsi)
movq 0x38(%rbx), %rdi
movl $0x2, %edx
callq 0x28689
movq %rax, 0x38(%rbx)
movslq -0x8(%rax), %rdx
xorl %edi, %edi
movq %rax, %rsi
callq 0x59440
leaq 0x10(%rsp), %rsi
movq %rax, (%rsi)
movq 0x38(%rbx), %rdi
movl $0x8, %edx
callq 0x28689
movq %rax, 0x38(%rbx)
addq $0x18, %rsp
popq %rbx
popq %r14
retq
leaq 0x47f89(%rip), %rdi     # 0x9d013
leaq 0x46c2c(%rip), %rsi     # 0x9bcbd
movl $0x13ab, %edx           # imm = 0x13AB
jmp 0x550ab
leaq 0x47f91(%rip), %rdi     # 0x9d030
leaq 0x46c17(%rip), %rsi     # 0x9bcbd
movl $0x13ac, %edx           # imm = 0x13AC
callq 0x4ca32
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: verifyDumpPayload
int verifyDumpPayload(unsigned char *p, size_t len) {
    unsigned char *footer;
    uint16_t rdbver;
    uint64_t crc;

    /* At least 2 bytes of RDB version and 8 of CRC64 should be present. */
    // 因为序列化数据至少包含 2 个字节的 RDB 版本
    // 以及 8 个字节的 CRC64 校验和
    // 所以序列化数据不可能少于 10 个字节
    if (len < 10) return REDIS_ERR;

    // 指向数据的最后 10 个字节
    footer = p+(len-10);

    /* Verify RDB version */
    // 检查序列化数据的版本号，看是否和当前实例使用的版本号一致
    rdbver = (footer[1] << 8) | footer[0];
    if (rdbver != REDIS_RDB_VERSION) return REDIS_ERR;

    /* Verify CRC64 */
    // 检查数据的 CRC64 校验和是否正确
    crc = crc64(0,p,len-8);
    memrev64ifbe(&crc);
    return (memcmp(&crc,footer+2,8) == 0) ? REDIS_OK : REDIS_ERR;
}

// Assembly:
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpq $0xa, %rsi
jb 0x550ff
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r14
cmpw $0x6, -0xa(%rdi,%rsi)
jne 0x550f8
leaq -0x8(%rbx), %rdx
xorl %edi, %edi
movq %r14, %rsi
callq 0x59440
movq %rax, %rcx
movq %rax, (%rsp)
xorl %eax, %eax
cmpq -0x8(%r14,%rbx), %rcx
setne %al
negl %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: dumpCommand
void dumpCommand(redisClient *c) {
    robj *o, *dumpobj;
    rio payload;

    /* Check if the key is here. */
    // 取出给定键的值
    if ((o = lookupKeyRead(c->db,c->argv[1])) == NULL) {
        addReply(c,shared.nullbulk);
        return;
    }

    /* Create the DUMP encoded representation. */
    // 创建给定值的一个 DUMP 编码表示
    createDumpPayload(&payload,o);

    /* Transfer to the client */
    // 将编码后的键值对数据返回给客户端
    dumpobj = createObject(REDIS_STRING,payload.io.buffer.ptr);
    addReplyBulk(c,dumpobj);
    decrRefCount(dumpobj);

    return;
}

// Assembly:
pushq %r14
pushq %rbx
subq $0x58, %rsp
movq %rdi, %rbx
movq 0x8(%rdi), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x3163a
testq %rax, %rax
je 0x55159
leaq 0x8(%rsp), %r14
movq %r14, %rdi
movq %rax, %rsi
callq 0x54ffc
movq 0x38(%r14), %rsi
xorl %edi, %edi
callq 0x3059c
movq %rax, %r14
movq %rbx, %rdi
movq %rax, %rsi
callq 0x2e204
movq %r14, %rdi
callq 0x30b0c
addq $0x58, %rsp
popq %rbx
popq %r14
retq
leaq 0x756a0(%rip), %rax     # 0xca800
movq 0x50(%rax), %rsi
movq %rbx, %rdi
addq $0x58, %rsp
popq %rbx
popq %r14
jmp 0x2d97c
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: readonlyCommand
void readonlyCommand(redisClient *c) {
    if (server.cluster_enabled == 0) {
        addReplyError(c,"This instance has cluster support disabled");
        return;
    }
    c->flags |= REDIS_READONLY;
    addReply(c,shared.ok);
}

// Assembly:
leaq 0x74304(%rip), %rax     # 0xc9fa8
cmpl $0x0, 0x7bc(%rax)
je 0x55cc4
orb $0x2, 0x92(%rdi)
leaq 0x74b45(%rip), %rax     # 0xca800
movq 0x8(%rax), %rsi
jmp 0x2d97c
leaq 0x46c7f(%rip), %rsi     # 0x9c94a
jmp 0x2dc63
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/scripting.c
// Function: luaPushError
void luaPushError(lua_State *lua, char *error) {
    lua_Debug dbg;

    lua_newtable(lua);
    lua_pushstring(lua,"err");

    /* Attempt to figure out where this function was called, if possible */
    if(lua_getstack(lua, 1, &dbg) && lua_getinfo(lua, "nSl", &dbg)) {
        sds msg = sdscatprintf(sdsempty(), "%s: %d: %s",
            dbg.source, dbg.currentline, error);
        lua_pushstring(lua, msg);
        sdsfree(msg);
    } else {
        lua_pushstring(lua, error);
    }
    lua_settable(lua,-3);
}

// Assembly:
pushq %r14
pushq %rbx
subq $0x78, %rsp
movq %rsi, %r14
movq %rdi, %rbx
xorl %esi, %esi
xorl %edx, %edx
callq 0x665ac
leaq 0x3f15b(%rip), %rsi     # 0x9596d
movq %rbx, %rdi
callq 0x662b5
movq %rsp, %rdx
movq %rbx, %rdi
movl $0x1, %esi
callq 0x66e55
testl %eax, %eax
je 0x5687e
leaq 0x46e13(%rip), %rsi     # 0x9d648
movq %rsp, %rdx
movq %rbx, %rdi
callq 0x66fce
testl %eax, %eax
je 0x5687e
callq 0x2845e
movq 0x20(%rsp), %rdx
movl 0x28(%rsp), %ecx
leaq 0x46df3(%rip), %rsi     # 0x9d64c
movq %rax, %rdi
movq %r14, %r8
xorl %eax, %eax
callq 0x28a5e
movq %rax, %r14
movq %rbx, %rdi
movq %rax, %rsi
callq 0x662b5
movq %r14, %rdi
callq 0x2850d
jmp 0x56889
movq %rbx, %rdi
movq %r14, %rsi
callq 0x662b5
movq %rbx, %rdi
movl $0xfffffffd, %esi       # imm = 0xFFFFFFFD
callq 0x666a8
addq $0x78, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/scripting.c
// Function: luaLogCommand
int luaLogCommand(lua_State *lua) {
    int j, argc = lua_gettop(lua);
    int level;
    sds log;

    if (argc < 2) {
        luaPushError(lua, "redis.log() requires two arguments or more.");
        return 1;
    } else if (!lua_isnumber(lua,-argc)) {
        luaPushError(lua, "First argument must be a number (log level).");
        return 1;
    }
    level = lua_tonumber(lua,-argc);
    if (level < REDIS_DEBUG || level > REDIS_WARNING) {
        luaPushError(lua, "Invalid debug level.");
        return 1;
    }

    /* Glue together all the arguments */
    log = sdsempty();
    for (j = 1; j < argc; j++) {
        size_t len;
        char *s;

        s = (char*)lua_tolstring(lua,(-argc)+j,&len);
        if (s) {
            if (j != 1) log = sdscatlen(log," ",1);
            log = sdscatlen(log,s,len);
        }
    }
    redisLogRaw(level,log);
    sdsfree(log);
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
callq 0x65ae0
cmpl $0x1, %eax
jg 0x5701e
leaq 0x467b8(%rip), %rsi     # 0x9d7d4
jmp 0x57056
movl %eax, %r15d
movl %eax, %ebp
negl %ebp
movq %rbx, %rdi
movl %ebp, %esi
callq 0x65ea7
testl %eax, %eax
je 0x5704f
movq %rbx, %rdi
movl %ebp, %esi
callq 0x66008
cvttsd2si %xmm0, %eax
cmpl $0x4, %eax
jb 0x57072
leaq 0x467e0(%rip), %rsi     # 0x9d82d
jmp 0x57056
leaq 0x467aa(%rip), %rsi     # 0x9d800
movq %rbx, %rdi
callq 0x567f5
movl $0x1, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %eax, 0xc(%rsp)
callq 0x2845e
movq %rax, %r14
movl $0x1, %ebp
subl %r15d, %ebp
xorl %r12d, %r12d
leaq 0x10(%rsp), %r15
leal (%r12,%rbp), %esi
movq %rbx, %rdi
movq %r15, %rdx
callq 0x6608c
testq %rax, %rax
je 0x570d4
movq %rax, %r13
testl %r12d, %r12d
je 0x570c1
movl $0x1, %edx
movq %r14, %rdi
leaq 0x43356(%rip), %rsi     # 0x9a40f
callq 0x28689
movq %rax, %r14
movq 0x10(%rsp), %rdx
movq %r14, %rdi
movq %r13, %rsi
callq 0x28689
movq %rax, %r14
incl %r12d
movl %ebp, %eax
addl %r12d, %eax
jne 0x5708e
movl 0xc(%rsp), %edi
movq %r14, %rsi
callq 0x230d4
movq %r14, %rdi
callq 0x2850d
xorl %eax, %eax
jmp 0x57063
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/scripting.c
// Function: luaMaskCountHook
void luaMaskCountHook(lua_State *lua, lua_Debug *ar) {
    long long elapsed;
    REDIS_NOTUSED(ar);
    REDIS_NOTUSED(lua);

    // 计算已执行时间
    elapsed = mstime() - server.lua_time_start;
    // 执行已超时
    if (elapsed >= server.lua_time_limit && server.lua_timedout == 0) {

        // 打印 LOG
        redisLog(REDIS_WARNING,"Lua slow script detected: still in execution after %lld milliseconds. You can try killing the script using the SCRIPT KILL command.",elapsed);

        // 设置状态
        server.lua_timedout = 1;

        /* Once the script timeouts we reenter the event loop to permit others
         * to call SCRIPT KILL or SHUTDOWN NOSAVE if needed. For this reason
         * we need to mask the client executing the script from the event loop.
         * If we don't do that the client may disconnect and could no longer be
         * here when the EVAL command will return. */
         // 当脚本运行超时时，将正在执行的客户端从读事件中移除
         // 并允许其他客户端执行 SCRIPT KILL 或者 SHUTDOWN NOSAVE
         aeDeleteFileEvent(server.el, server.lua_caller->fd, AE_READABLE);
    }

    // 在脚本上下文中，启动文件事件处理（等待 SCRIPT KILL 或 SHUTDOWN NOSAVE）
    if (server.lua_timedout) processEventsWhileBlocked();
    // 如果接到 SCRIPT KILL ，那么杀死脚本
    if (server.lua_kill) {
        redisLog(REDIS_WARNING,"Lua script killed by user with SCRIPT KILL.");
        lua_pushstring(lua,"Script killed by user with SCRIPT KILL...");
        lua_error(lua);
    }
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
callq 0x23461
leaq 0x72e9c(%rip), %r14     # 0xc9fa8
subq 0x808(%r14), %rax
cmpq 0x800(%r14), %rax
setge %dl
movl 0x818(%r14), %ecx
testl %ecx, %ecx
sete %sil
andb %dl, %sil
cmpb $0x1, %sil
jne 0x57172
leaq 0x46708(%rip), %rsi     # 0x9d842
movl $0x3, %edi
movq %rax, %rdx
xorl %eax, %eax
callq 0x23223
movl $0x1, 0x818(%r14)
movq 0x28(%r14), %rdi
movq 0x7f0(%r14), %rax
movl (%rax), %esi
movl $0x1, %edx
callq 0x20ce8
movl 0x818(%r14), %ecx
testl %ecx, %ecx
je 0x5717b
callq 0x2fc38
cmpl $0x0, 0x81c(%r14)
je 0x571b6
leaq 0x4673a(%rip), %rsi     # 0x9d8c6
movl $0x3, %edi
xorl %eax, %eax
callq 0x23223
leaq 0x46753(%rip), %rsi     # 0x9d8f2
movq %rbx, %rdi
callq 0x662b5
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0x66bbd
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/scripting.c
// Function: luaLoadLibraries
void luaLoadLibraries(lua_State *lua) {

    // 基础库
    luaLoadLib(lua, "", luaopen_base);

    // table 库
    luaLoadLib(lua, LUA_TABLIBNAME, luaopen_table);

    // 字符串库
    luaLoadLib(lua, LUA_STRLIBNAME, luaopen_string);

    // 数学库
    luaLoadLib(lua, LUA_MATHLIBNAME, luaopen_math);

    // debug 库
    luaLoadLib(lua, LUA_DBLIBNAME, luaopen_debug); 

    // cjson 库
    luaLoadLib(lua, "cjson", luaopen_cjson);

    // struct 库
    luaLoadLib(lua, "struct", luaopen_struct);

    // cmsgpack 库
    luaLoadLib(lua, "cmsgpack", luaopen_cmsgpack);

#if 0 /* Stuff that we don't load currently, for sandboxing concerns. */
    luaLoadLib(lua, LUA_LOADLIBNAME, luaopen_package);
    luaLoadLib(lua, LUA_OSLIBNAME, luaopen_os);
#endif
}

// Assembly:
pushq %rbx
movq %rdi, %rbx
leaq 0x40143(%rip), %rsi     # 0x97341
leaq 0x1acab(%rip), %rdx     # 0x71eb0
callq 0x571be
leaq 0x4a8d4(%rip), %rsi     # 0xa1ae5
leaq 0x1d3c8(%rip), %rdx     # 0x745e0
movq %rbx, %rdi
callq 0x571be
leaq 0x4a811(%rip), %rsi     # 0xa1a38
leaq 0x1dda2(%rip), %rdx     # 0x74fd0
movq %rbx, %rdi
callq 0x571be
leaq 0x466df(%rip), %rsi     # 0x9d91c
leaq 0x1cc98(%rip), %rdx     # 0x73edc
movq %rbx, %rdi
callq 0x571be
leaq 0x4c645(%rip), %rsi     # 0xa3898
leaq 0x1bfea(%rip), %rdx     # 0x73244
movq %rbx, %rdi
callq 0x571be
leaq 0x466b8(%rip), %rsi     # 0x9d921
leaq 0x1f8b8(%rip), %rdx     # 0x76b28
movq %rbx, %rdi
callq 0x571be
leaq 0x466a8(%rip), %rsi     # 0x9d927
leaq 0x21022(%rip), %rdx     # 0x782a8
movq %rbx, %rdi
callq 0x571be
leaq 0x46699(%rip), %rsi     # 0x9d92e
leaq 0x21fbf(%rip), %rdx     # 0x7925b
movq %rbx, %rdi
popq %rbx
jmp 0x571be
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/scripting.c
// Function: scriptingEnableGlobalsProtection
void scriptingEnableGlobalsProtection(lua_State *lua) {
    char *s[32];
    sds code = sdsempty();
    int j = 0;

    /* strict.lua from: http://metalua.luaforge.net/src/lib/strict.lua.html.
     * Modified to be adapted to Redis. */
    s[j++]="local mt = {}\n";
    s[j++]="setmetatable(_G, mt)\n";
    s[j++]="mt.__newindex = function (t, n, v)\n";
    s[j++]="  if debug.getinfo(2) then\n";
    s[j++]="    local w = debug.getinfo(2, \"S\").what\n";
    s[j++]="    if w ~= \"main\" and w ~= \"C\" then\n";
    s[j++]="      error(\"Script attempted to create global variable '\"..tostring(n)..\"'\", 2)\n";
    s[j++]="    end\n";
    s[j++]="  end\n";
    s[j++]="  rawset(t, n, v)\n";
    s[j++]="end\n";
    s[j++]="mt.__index = function (t, n)\n";
    s[j++]="  if debug.getinfo(2) and debug.getinfo(2, \"S\").what ~= \"C\" then\n";
    s[j++]="    error(\"Script attempted to access unexisting global variable '\"..tostring(n)..\"'\", 2)\n";
    s[j++]="  end\n";
    s[j++]="  return rawget(t, n)\n";
    s[j++]="end\n";
    s[j++]=NULL;

    for (j = 0; s[j] != NULL; j++) code = sdscatlen(code,s[j],strlen(s[j]));
    luaL_loadbuffer(lua,code,sdslen(code),"@enable_strict_lua");
    lua_pcall(lua,0,0,0);
    sdsfree(code);
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x108, %rsp            # imm = 0x108
movq %rdi, %rbx
callq 0x2845e
movq %rax, %r14
leaq 0x4665d(%rip), %r15     # 0x9d940
leaq 0x8(%rsp), %r12
movq %r15, -0x8(%r12)
leaq 0x4665b(%rip), %rax     # 0x9d94f
movq %rax, (%r12)
leaq 0x46666(%rip), %rax     # 0x9d965
movq %rax, 0x8(%r12)
leaq 0x4667e(%rip), %rax     # 0x9d989
movq %rax, 0x10(%r12)
leaq 0x4668e(%rip), %rax     # 0x9d9a5
movq %rax, 0x18(%r12)
leaq 0x466ac(%rip), %rax     # 0x9d9cf
movq %rax, 0x20(%r12)
leaq 0x466c6(%rip), %rax     # 0x9d9f5
movq %rax, 0x28(%r12)
leaq 0x4670c(%rip), %rax     # 0x9da47
movq %rax, 0x30(%r12)
leaq 0x46702(%rip), %rax     # 0x9da49
movq %rax, 0x38(%r12)
leaq 0x466fd(%rip), %rcx     # 0x9da50
movq %rcx, 0x40(%r12)
leaq 0x468b5(%rip), %rcx     # 0x9dc14
movq %rcx, 0x48(%r12)
leaq 0x466f8(%rip), %rdx     # 0x9da63
movq %rdx, 0x50(%r12)
leaq 0x4670a(%rip), %rdx     # 0x9da81
movq %rdx, 0x58(%r12)
leaq 0x46740(%rip), %rdx     # 0x9dac3
movq %rdx, 0x60(%r12)
movq %rax, 0x68(%r12)
leaq 0x4678a(%rip), %rax     # 0x9db1e
movq %rax, 0x70(%r12)
movq %rcx, 0x78(%r12)
movq $0x0, 0x80(%r12)
movq %r15, %rdi
callq 0x1f4f0
movq %r14, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x28689
movq %rax, %r14
movq (%r12), %r15
addq $0x8, %r12
testq %r15, %r15
jne 0x573aa
movslq -0x8(%r14), %rdx
leaq 0x4675a(%rip), %rcx     # 0x9db35
movq %rbx, %rdi
movq %r14, %rsi
callq 0x71df0
movq %rbx, %rdi
xorl %esi, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x66941
movq %r14, %rdi
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x2850d
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/scripting.c
// Function: scriptingReset
void scriptingReset(void) {

    // 释放环境
    scriptingRelease();

    // 初始化环境
    scriptingInit();
}

// Assembly:
pushq %rbx
leaq 0x726ee(%rip), %rbx     # 0xc9fa8
movq 0x7f8(%rbx), %rdi
callq 0x229a9
movq 0x7e0(%rbx), %rdi
callq 0x6d74b
popq %rbx
jmp 0x5740a
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/bio.c
// Function: bioInit
void bioInit(void) {
    pthread_attr_t attr;
    pthread_t thread;
    size_t stacksize;
    int j;

    /* Initialization of state vars and objects 
     *
     * 初始化 job 队列，以及线程状态
     */
    for (j = 0; j < REDIS_BIO_NUM_OPS; j++) {
        pthread_mutex_init(&bio_mutex[j],NULL);
        pthread_cond_init(&bio_condvar[j],NULL);
        bio_jobs[j] = listCreate();
        bio_pending[j] = 0;
    }

    /* Set the stack size as by default it may be small in some system 
     *
     * 设置栈大小
     */
    pthread_attr_init(&attr);
    pthread_attr_getstacksize(&attr,&stacksize);
    if (!stacksize) stacksize = 1; /* The world is full of Solaris Fixes */
    while (stacksize < REDIS_THREAD_STACK_SIZE) stacksize *= 2;
    pthread_attr_setstacksize(&attr, stacksize);

    /* Ready to spawn our threads. We use the single argument the thread
     * function accepts in order to pass the job ID the thread is
     * responsible of. 
     *
     * 创建线程
     */
    for (j = 0; j < REDIS_BIO_NUM_OPS; j++) {
        void *arg = (void*)(unsigned long) j;
        if (pthread_create(&thread,&attr,bioProcessBackgroundJobs,arg) != 0) {
            redisLog(REDIS_WARNING,"Fatal: Can't initialize Background Jobs.");
            exit(1);
        }
        bio_threads[j] = thread;
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
leaq 0x8632b(%rip), %rdi     # 0xde7f0
xorl %ebx, %ebx
xorl %esi, %esi
callq 0x1f420
leaq 0x8636b(%rip), %rdi     # 0xde840
xorl %esi, %esi
callq 0x1f510
callq 0x203fc
movq %rax, 0x863b8(%rip)     # 0xde8a0
movq %rbx, 0x863c1(%rip)     # 0xde8b0
leaq 0x86322(%rip), %rdi     # 0xde818
xorl %esi, %esi
callq 0x1f420
leaq 0x8636c(%rip), %rdi     # 0xde870
xorl %esi, %esi
callq 0x1f510
callq 0x203fc
movq %rax, 0x86391(%rip)     # 0xde8a8
movq %rbx, 0x8639a(%rip)     # 0xde8b8
leaq 0x10(%rsp), %rbx
movq %rbx, %rdi
callq 0x1f9e0
movq %rsp, %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0x1f870
movq (%r14), %rsi
testq %rsi, %rsi
je 0x5854c
cmpq $0x3fffff, %rsi         # imm = 0x3FFFFF
jbe 0x58551
jmp 0x58563
movl $0x1, %esi
movq %rsi, %rax
addq %rsi, %rsi
cmpq $0x200000, %rax         # imm = 0x200000
jb 0x58551
movq %rsi, (%rsp)
leaq 0x10(%rsp), %rbx
movq %rbx, %rdi
callq 0x1f760
movb $0x1, %bpl
xorl %r14d, %r14d
leaq 0x68(%rip), %r15        # 0x585e5
leaq 0x8(%rsp), %r12
leaq 0x86337(%rip), %r13     # 0xde8c0
movq %r12, %rdi
movq %rbx, %rsi
movq %r15, %rdx
movq %r14, %rcx
callq 0x1f490
testl %eax, %eax
jne 0x585c8
movq 0x8(%rsp), %rax
movq %rax, (%r13,%r14,8)
movl $0x1, %r14d
testb $0x1, %bpl
movl $0x0, %ebp
jne 0x58589
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x459bb(%rip), %rsi     # 0x9df8a
movl $0x3, %edi
xorl %eax, %eax
callq 0x23223
movl $0x1, %edi
callq 0x1f2b0
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/bio.c
// Function: bioKillThreads
void bioKillThreads(void) {
    int err, j;

    for (j = 0; j < REDIS_BIO_NUM_OPS; j++) {
        if (pthread_cancel(bio_threads[j]) == 0) {
            if ((err = pthread_join(bio_threads[j],NULL)) != 0) {
                redisLog(REDIS_WARNING,
                    "Bio thread for job type #%d can be joined: %s",
                        j, strerror(err));
            } else {
                redisLog(REDIS_WARNING,
                    "Bio thread for job type #%d terminated",j);
            }
        }
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movb $0x1, %bpl
leaq 0x860bb(%rip), %r12     # 0xde8c0
leaq 0x4583b(%rip), %rbx     # 0x9e047
leaq 0x45806(%rip), %r14     # 0x9e019
xorl %r15d, %r15d
movq (%r12,%r15,8), %rdi
callq 0x1f750
testl %eax, %eax
jne 0x58862
movq (%r12,%r15,8), %rdi
xorl %esi, %esi
callq 0x1f080
testl %eax, %eax
je 0x58850
movl %eax, %edi
callq 0x1f630
movl $0x3, %edi
movq %r14, %rsi
movl %r15d, %edx
movq %rax, %rcx
xorl %eax, %eax
callq 0x23223
jmp 0x58862
movl $0x3, %edi
movq %rbx, %rsi
movl %r15d, %edx
xorl %eax, %eax
callq 0x23223
movl $0x1, %r15d
testb $0x1, %bpl
movl $0x0, %ebp
jne 0x58816
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/rio.c
// Function: rioWriteBulkString
size_t rioWriteBulkString(rio *r, const char *buf, size_t len) {
    size_t nwritten;

    // 写入 $<count>\r\n
    if ((nwritten = rioWriteBulkCount(r,'$',len)) == 0) return 0;

    // 写入 <payload>
    if (len > 0 && rioWrite(r,buf,len) == 0) return 0;

    // 写入 \r\n
    if (rioWrite(r,"\r\n",2) == 0) return 0;

    // 返回写入总量
    return nwritten+len+2;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdx, %rbx
movq %rsi, %r13
movq %rdi, %r14
movl $0x24, %esi
callq 0x5891c
testq %rax, %rax
je 0x58a9e
movq %rax, (%rsp)
testq %rbx, %rbx
je 0x58a39
xorl %r15d, %r15d
movq %rbx, %r12
movq 0x18(%r14), %rax
movq 0x30(%r14), %rcx
cmpq %r12, %rcx
movq %r12, %rbp
cmovbq %rcx, %rbp
testq %rcx, %rcx
cmoveq %r12, %rbp
testq %rax, %rax
je 0x58a1b
movq %r14, %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq *%rax
movq %r14, %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq *0x8(%r14)
testq %rax, %rax
je 0x58aa1
addq %rbp, %r13
addq %rbp, 0x28(%r14)
subq %rbp, %r12
jne 0x589f2
leaq 0x40ccf(%rip), %r13     # 0x9970f
movl $0x2, %r12d
xorl %r15d, %r15d
movq 0x18(%r14), %rax
movq 0x30(%r14), %rcx
cmpq %r12, %rcx
movq %r12, %rbp
cmovbq %rcx, %rbp
testq %rcx, %rcx
cmoveq %r12, %rbp
testq %rax, %rax
je 0x58a72
movq %r14, %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq *%rax
movq %r14, %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq *0x8(%r14)
testq %rax, %rax
je 0x58aa1
addq %rbp, %r13
addq %rbp, 0x28(%r14)
subq %rbp, %r12
jne 0x58a49
movq (%rsp), %rax
leaq (%rbx,%rax), %r15
addq $0x2, %r15
jmp 0x58aa1
xorl %r15d, %r15d
movq %r15, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/rio.c
// Function: rioBufferRead
static size_t rioBufferRead(rio *r, void *buf, size_t len) {

    // r 中的内容的长度不足 len 
    if (sdslen(r->io.buffer.ptr)-r->io.buffer.pos < len)
        return 0; /* not enough buffer to return len bytes. */
    
    // 复制 r 中的内容到 buf
    memcpy(buf,r->io.buffer.ptr+r->io.buffer.pos,len);
    r->io.buffer.pos += len;

    return 1;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rdx, %rbx
movq 0x38(%rdi), %rax
movq 0x40(%rdi), %rcx
movslq -0x8(%rax), %rdx
subq %rcx, %rdx
cmpq %rbx, %rdx
jae 0x58bca
xorl %eax, %eax
jmp 0x58be7
movq %rdi, %r14
addq %rcx, %rax
movq %rsi, %rdi
movq %rax, %rsi
movq %rbx, %rdx
callq 0x1fbd0
addq %rbx, 0x40(%r14)
movl $0x1, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/bitops.c
// Function: getBitOffsetFromArgument
static int getBitOffsetFromArgument(redisClient *c, robj *o, size_t *offset) {
    long long loffset;
    char *err = "bit offset is not an integer or out of range";

    if (getLongLongFromObjectOrReply(c,o,&loffset,err) != REDIS_OK)
        return REDIS_ERR;

    /* Limit offset to 512MB in bytes */
    if ((loffset < 0) || ((unsigned long long)loffset >> 3) >= (512*1024*1024))
    {
        addReplyError(c,err);
        return REDIS_ERR;
    }

    *offset = (size_t)loffset;
    return REDIS_OK;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x10, %rsp
movq %rdx, %r15
movq %rdi, %r14
leaq 0x45552(%rip), %rcx     # 0x9ed7b
leaq 0x8(%rsp), %rdx
callq 0x31355
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
testl %eax, %eax
jne 0x59860
movq 0x8(%rsp), %rax
movq %rax, %rcx
shrq $0x20, %rcx
je 0x5985b
leaq 0x4552a(%rip), %rsi     # 0x9ed7b
movq %r14, %rdi
callq 0x2dc63
jmp 0x59860
movq %rax, (%r15)
xorl %ebx, %ebx
movl %ebx, %eax
addq $0x10, %rsp
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/bitops.c
// Function: getbitCommand
void getbitCommand(redisClient *c) {
    robj *o;
    char llbuf[32];
    size_t bitoffset;
    size_t byte, bit;
    size_t bitval = 0;

    // 读取 offset 参数
    if (getBitOffsetFromArgument(c,c->argv[2],&bitoffset) != REDIS_OK)
        return;

    // 查找对象，并进行类型检查
    if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL ||
        checkType(c,o,REDIS_STRING)) return;

    // 计算出 offset 所指定的位所在的字节
    byte = bitoffset >> 3;
    // 计算出位所在的位置
    bit = 7 - (bitoffset & 0x7);

    // 取出位
    if (sdsEncodedObject(o)) {
        // 字符串编码，直接取值
        if (byte < sdslen(o->ptr))
            bitval = ((uint8_t*)o->ptr)[byte] & (1 << bit);
    } else {
        // 整数编码，先转换成字符串，再取值
        if (byte < (size_t)ll2string(llbuf,sizeof(llbuf),(long)o->ptr))
            bitval = llbuf[byte] & (1 << bit);
    }

    // 返回位
    addReply(c, bitval ? shared.cone : shared.czero);
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x30, %rsp
movq %rdi, %rbx
movq 0x38(%rdi), %rax
movq 0x10(%rax), %rsi
leaq 0x8(%rsp), %rdx
callq 0x59813
testl %eax, %eax
je 0x598a0
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
leaq 0x70f51(%rip), %r12     # 0xca800
movq 0x20(%r12), %rdx
movq %rbx, %rdi
callq 0x31745
testq %rax, %rax
je 0x59892
movq %rax, %r15
movq %rbx, %rdi
movq %rax, %rsi
xorl %edx, %edx
callq 0x30bbf
testl %eax, %eax
jne 0x59892
movq 0x8(%rsp), %r14
movq %r14, %r13
shrq $0x3, %r13
movl (%r15), %eax
shrl $0x4, %eax
testb $0x7, %al
jne 0x598fd
movq 0x8(%r15), %rax
movslq -0x8(%rax), %rcx
cmpq %rcx, %r13
jae 0x59941
addq %r13, %rax
jmp 0x5991f
movq 0x8(%r15), %rdx
leaq 0x10(%rsp), %rdi
movl $0x20, %esi
callq 0x300c7
cltq
cmpq %rax, %r13
jae 0x59941
leaq (%rsp,%r13), %rax
addq $0x10, %rax
movzbl (%rax), %eax
notb %r14b
andb $0x7, %r14b
movl $0x1, %edx
movl %r14d, %ecx
shll %cl, %edx
xorl %ecx, %ecx
andl %eax, %edx
setne %cl
movq 0x20(%r12,%rcx,8), %rsi
jmp 0x59946
movq 0x20(%r12), %rsi
movq %rbx, %rdi
callq 0x2d97c
jmp 0x59892
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: releaseSentinelRedisInstance
void releaseSentinelRedisInstance(sentinelRedisInstance *ri) {

    /* Release all its slaves or sentinels if any. */
    // 释放（可能有的）sentinel 和 slave
    dictRelease(ri->sentinels);
    dictRelease(ri->slaves);

    /* Release hiredis connections. */
    // 释放连接
    if (ri->cc) sentinelKillLink(ri,ri->cc);
    if (ri->pc) sentinelKillLink(ri,ri->pc);

    /* Free other resources. */
    // 释放其他资源
    sdsfree(ri->name);
    sdsfree(ri->runid);
    sdsfree(ri->notification_script);
    sdsfree(ri->client_reconfig_script);
    sdsfree(ri->slave_master_host);
    sdsfree(ri->leader);
    sdsfree(ri->auth_pass);
    releaseSentinelAddr(ri->addr);

    /* Clear state into the master if needed. */
    // 清除故障转移带来的状态
    if ((ri->flags & SRI_SLAVE) && (ri->flags & SRI_PROMOTED) && ri->master)
        ri->master->promoted_slave = NULL;

    zfree(ri);
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0xc0(%rdi), %rdi
callq 0x229a9
movq 0xc8(%rbx), %rdi
callq 0x229a9
movq 0x28(%rbx), %rsi
testq %rsi, %rsi
je 0x5a424
movq %rbx, %rdi
callq 0x5be4f
movq 0x30(%rbx), %rsi
testq %rsi, %rsi
je 0x5a435
movq %rbx, %rdi
callq 0x5be4f
movq 0x8(%rbx), %rdi
callq 0x2850d
movq 0x10(%rbx), %rdi
callq 0x2850d
movq 0x160(%rbx), %rdi
callq 0x2850d
movq 0x168(%rbx), %rdi
callq 0x2850d
movq 0x100(%rbx), %rdi
callq 0x2850d
movq 0x118(%rbx), %rdi
callq 0x2850d
movq 0xd8(%rbx), %rdi
callq 0x2850d
movq 0x20(%rbx), %r14
movq (%r14), %rdi
callq 0x2850d
movq %r14, %rdi
callq 0x29af7
movl (%rbx), %eax
notl %eax
testl $0x102, %eax            # imm = 0x102
jne 0x5a4b9
movq 0xf8(%rbx), %rax
testq %rax, %rax
je 0x5a4b9
movq $0x0, 0x158(%rax)
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0x29af7
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: initSentinel
void initSentinel(void) {
    int j;

    /* Remove usual Redis commands from the command table, then just add
     * the SENTINEL command. */

    // 清空 Redis 服务器的命令表（该表用于普通模式）
    dictEmpty(server.commands,NULL);
    // 将 SENTINEL 模式所用的命令添加进命令表
    for (j = 0; j < sizeof(sentinelcmds)/sizeof(sentinelcmds[0]); j++) {
        int retval;
        struct redisCommand *cmd = sentinelcmds+j;

        retval = dictAdd(server.commands, sdsnew(cmd->name), cmd);
        redisAssert(retval == DICT_OK);
    }

    /* Initialize various data structures. */
    /* 初始化 Sentinel 的状态 */
    // 初始化纪元
    sentinel.current_epoch = 0;

    // 初始化保存主服务器信息的字典
    sentinel.masters = dictCreate(&instancesDictType,NULL);

    // 初始化 TILT 模式的相关选项
    sentinel.tilt = 0;
    sentinel.tilt_start_time = 0;
    sentinel.previous_time = mstime();

    // 初始化脚本相关选项
    sentinel.running_scripts = 0;
    sentinel.scripts_queue = listCreate();
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
leaq 0x6f179(%rip), %r15     # 0xc9fa8
movq 0x18(%r15), %rdi
xorl %r12d, %r12d
xorl %esi, %esi
callq 0x22f17
leaq 0x6ed9c(%rip), %r13     # 0xc9be0
leaq (%r12,%r13), %rbx
movq 0x18(%r15), %r14
movq (%r12,%r13), %rdi
callq 0x28486
movq %r14, %rdi
movq %rax, %rsi
movq %rbx, %rdx
callq 0x2249c
testl %eax, %eax
jne 0x5aec7
addq $0x50, %r12
cmpq $0x2d0, %r12            # imm = 0x2D0
jne 0x5ae44
xorl %ebx, %ebx
movq %rbx, 0x83a6b(%rip)     # 0xde8e8
leaq 0x6ecfc(%rip), %rdi     # 0xc9b80
xorl %esi, %esi
callq 0x2217b
movq %rax, 0x83a5e(%rip)     # 0xde8f0
movl %ebx, 0x83a60(%rip)     # 0xde8f8
movq %rbx, 0x83a61(%rip)     # 0xde900
callq 0x23461
movq %rax, 0x83a5d(%rip)     # 0xde908
movl %ebx, 0x83a4b(%rip)     # 0xde8fc
callq 0x203fc
movq %rax, 0x83a53(%rip)     # 0xde910
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
leaq 0x3d988(%rip), %rdi     # 0x98856
leaq 0x43f4f(%rip), %rsi     # 0x9ee24
movl $0x28c, %edx            # imm = 0x28C
callq 0x4ca32
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelIsRunning
void sentinelIsRunning(void) {
    redisLog(REDIS_WARNING,"Sentinel runid is %s", server.runid);

    // Sentinel 不能在没有配置文件的情况下执行
    if (server.configfile == NULL) {
        redisLog(REDIS_WARNING,
            "Sentinel started without a config file. Exiting...");
        exit(1);
    } else if (access(server.configfile,W_OK) == -1) {
        redisLog(REDIS_WARNING,
            "Sentinel config file %s is not writable: %s. Exiting...",
            server.configfile,strerror(errno));
        exit(1);
    }

    /* We want to generate a +monitor event for every configured master
     * at startup. */
    sentinelGenerateInitialMonitorEvents();
}

// Assembly:
pushq %rbx
leaq 0x6f0b7(%rip), %rbx     # 0xc9fa8
leaq 0x58(%rbx), %rdx
leaq 0x43f33(%rip), %rsi     # 0x9ee2f
movl $0x3, %edi
xorl %eax, %eax
callq 0x23223
movq (%rbx), %rdi
testq %rdi, %rdi
je 0x5af25
movl $0x2, %esi
callq 0x1fa20
cmpl $-0x1, %eax
je 0x5af3a
popq %rbx
jmp 0x5af6c
leaq 0x43f18(%rip), %rsi     # 0x9ee44
movl $0x3, %edi
xorl %eax, %eax
callq 0x23223
jmp 0x5af62
movq (%rbx), %rbx
callq 0x1f810
movl (%rax), %edi
callq 0x1f630
leaq 0x43f27(%rip), %rsi     # 0x9ee77
movl $0x3, %edi
movq %rbx, %rdx
movq %rax, %rcx
xorl %eax, %eax
callq 0x23223
movl $0x1, %edi
callq 0x1f2b0
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelGenerateInitialMonitorEvents
void sentinelGenerateInitialMonitorEvents(void) {
    dictIterator *di;
    dictEntry *de;

    di = dictGetIterator(sentinel.masters);
    while((de = dictNext(di)) != NULL) {
        sentinelRedisInstance *ri = dictGetVal(de);
        sentinelEvent(REDIS_WARNING,"+monitor",ri,"%@ quorum %d",ri->quorum);
    }
    dictReleaseIterator(di);
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq 0x83978(%rip), %rdi     # 0xde8f0
callq 0x22a71
movq %rax, %rbx
movq %rax, %rdi
callq 0x22acf
testq %rax, %rax
je 0x5afc5
leaq 0x43f3e(%rip), %r14     # 0x9eed2
leaq 0x43f40(%rip), %r15     # 0x9eedb
movq 0x8(%rax), %rdx
movl 0xd0(%rdx), %r8d
movl $0x3, %edi
movq %r14, %rsi
movq %r15, %rcx
xorl %eax, %eax
callq 0x5b0ac
movq %rbx, %rdi
callq 0x22acf
testq %rax, %rax
jne 0x5af9b
movq %rbx, %rdi
popq %rbx
popq %r14
popq %r15
jmp 0x22b86
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: createSentinelAddr
sentinelAddr *createSentinelAddr(char *hostname, int port) {
    char buf[32];
    sentinelAddr *sa;

    // 检查端口号
    if (port <= 0 || port > 65535) {
        errno = EINVAL;
        return NULL;
    }

    // 检查并创建地址
    if (anetResolve(NULL,hostname,buf,sizeof(buf)) == ANET_ERR) {
        errno = ENOENT;
        return NULL;
    }

    // 创建并返回地址结构
    sa = zmalloc(sizeof(*sa));
    sa->ip = sdsnew(buf);
    sa->port = port;
    return sa;
}

// Assembly:
pushq %r14
pushq %rbx
subq $0x28, %rsp
movl %esi, %ebx
movl $0xffff0000, %eax       # imm = 0xFFFF0000
leal (%rbx,%rax), %ecx
cmpl %eax, %ecx
ja 0x5aff4
callq 0x1f810
movl $0x16, (%rax)
jmp 0x5b034
movq %rdi, %rsi
movq %rsp, %rdx
movl $0x20, %ecx
xorl %edi, %edi
callq 0x21780
cmpl $-0x1, %eax
je 0x5b029
movl $0x10, %edi
callq 0x299b5
movq %rax, %r14
movq %rsp, %rdi
callq 0x28486
movq %rax, (%r14)
movl %ebx, 0x8(%r14)
jmp 0x5b037
callq 0x1f810
movl $0x2, (%rax)
xorl %r14d, %r14d
movq %r14, %rax
addq $0x28, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelKillTimedoutScripts
void sentinelKillTimedoutScripts(void) {
    listNode *ln;
    listIter li;
    mstime_t now = mstime();

    // 遍历队列中的所有脚本
    listRewind(sentinel.scripts_queue,&li);
    while ((ln = listNext(&li)) != NULL) {
        sentinelScriptJob *sj = ln->value;

        // 选出那些正在执行，并且执行时间超过限制的脚本
        if (sj->flags & SENTINEL_SCRIPT_RUNNING &&
            (now - sj->start_time) > SENTINEL_SCRIPT_MAX_RUNTIME)
        {
            // 发送脚本超时事件
            sentinelEvent(REDIS_WARNING,"-script-timeout",NULL,"%s %ld",
                sj->argv[0], (long)sj->pid);

            // 杀死脚本进程
            kill(sj->pid,SIGKILL);
        }
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x10, %rsp
callq 0x23461
movq %rax, %rbx
movq 0x83060(%rip), %rdi     # 0xde910
movq %rsp, %r14
movq %r14, %rsi
callq 0x20637
movq %r14, %rdi
callq 0x20654
testq %rax, %rax
je 0x5b92d
movq %rsp, %r14
leaq 0x436d5(%rip), %r15     # 0x9efa7
leaq 0x3eb95(%rip), %r12     # 0x9a46e
movq 0x10(%rax), %r13
testb $0x1, (%r13)
je 0x5b920
movq %rbx, %rax
subq 0x10(%r13), %rax
cmpq $0xea61, %rax           # imm = 0xEA61
jl 0x5b920
movq 0x8(%r13), %rax
movq (%rax), %r8
movslq 0x18(%r13), %r9
movl $0x3, %edi
movq %r15, %rsi
xorl %edx, %edx
movq %r12, %rcx
xorl %eax, %eax
callq 0x5b0ac
movl 0x18(%r13), %edi
movl $0x9, %esi
callq 0x1f620
movq %r14, %rdi
callq 0x20654
testq %rax, %rax
jne 0x5b8d9
addq $0x10, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelRedisInstanceLookupSlave
sentinelRedisInstance *sentinelRedisInstanceLookupSlave(
                sentinelRedisInstance *ri, char *ip, int port)
{
    sds key;
    sentinelRedisInstance *slave;
  
    redisAssert(ri->flags & SRI_MASTER);
    key = sdscatprintf(sdsempty(),
        strchr(ip,':') ? "[%s]:%d" : "%s:%d",
        ip,port);
    slave = dictFetchValue(ri->slaves,key);
    sdsfree(key);
    return slave;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
testb $0x1, (%rdi)
je 0x5bf00
movl %edx, %ebp
movq %rsi, %r14
movq %rdi, %rbx
callq 0x2845e
movq %rax, %r15
movq %r14, %rdi
movl $0x3a, %esi
callq 0x1f790
testq %rax, %rax
leaq 0x3cae6(%rip), %rax     # 0x989a1
leaq 0x3b1cc(%rip), %rsi     # 0x9708e
cmoveq %rax, %rsi
movq %r15, %rdi
movq %r14, %rdx
movl %ebp, %ecx
xorl %eax, %eax
callq 0x28a5e
movq %rax, %r14
movq 0xc8(%rbx), %rdi
movq %rax, %rsi
callq 0x229cf
movq %rax, %rbx
movq %r14, %rdi
callq 0x2850d
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
leaq 0x43136(%rip), %rdi     # 0x9f03d
leaq 0x42f16(%rip), %rsi     # 0x9ee24
movl $0x5b1, %edx            # imm = 0x5B1
callq 0x4ca32
movl $0x1, %edi
callq 0x1f3b0