NDK持续打印

在一次联调中发现,NDK在不停打印”TCP: Keep Timeout”。在高吞吐的系统负载下,打印会大大降低系统性能,造成丢包、高延迟等后果。
为了解决这一问题,首先要确认该打印的原因。然后再想办法减少打印。

打印原因是TCP有保活定时器,当超时时会触发这条消息。当一条TCP连接建立后,当一段时间连接上没有收发数据时,TCP会发送保活消息。NDK的默认设置是线路静默2小时后开始发起保活,每隔75秒发送一次,连续10分钟无响应时断开该连接。

从NDK源码中搜索,马上找到了这条打印的代码:

========== stack/tcp/tcptime.c 109 109 ============     DbgPrintf(DBG_INFO,"TCP: Keep Timeout");

发现这是一条DBG_INFO级别的打印。NDK有四种不同的打印级别,分别对应于不同的信息级别。在源码中可以找到。

========== inc/os/osif.h 294 297 ============
#define DBG_INFO 1
#define DBG_WARN 2
#define DBG_ERROR 3
#define DBG_NONE 4

默认NDK的打印级别是信息级,即几乎所有消息都会打印出来。

========== inc/os/osif.h 80 80 ============
#define DEF_DBG_PRINT_LEVEL DBG_INFO

为了避免无关信息影响性能,可以在cfg文件中配置显示哪些级别的信息。例如需要只显示警告及以上消息时,在cfg文件中配置为:

Global.debugPrintLevel = Global.DBG_WARN;

然而在NDK2.23中,这个配置不能成功生效,原因是NDK有一个小的bug。当配置NDK的enableCodeGeneration为true时,会自动生成一些启动代码在Debug/configPkg/package/cfg/XX_pe64P.c中。这段自动生成的代码的ti_ndk_config_Global_stackThread()函数中,有一段代码:

    /* add the configuration settings for debug messages. */
    rc = 1;
    CfgAddEntry(hCfg, CFGTAG_OS, CFGITEM_OS_DBGPRINTLEVEL,
                 CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );

这里在NDK启动过程中调用CfgAddEntry配置了打印级别,然后配入的值rc并不随cfg中变化,而是固定为1。

为了解决这个问题,引入勾子函数NetworkOpenHook(),在其中再次配置打印级别:

    cfgParameter = DBG_WARN;
    CfgAddEntry(0, CFGTAG_OS, CFGITEM_OS_DBGPRINTLEVEL,
            CFG_ADDMODE_NOSAVE | CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&cfgParameter, 0 );

修改完成后打印系统恢复正常。

你可能感兴趣的:(NDK)