timezoneinfo的裁剪移植之uclibc/gclibc/openwrt的最详细实战版!

1.需求背景

因为项目需要,产品售卖到国外各个地区,需要能适配各个国家的不同时区,一些国家可能会有多个不同时区,并且还存在冬夏令时问题,都需要做到一次性的兼容。而目前板子上可用的flash空间也已经不足200KB,需要同时考虑对flash空间节省。

网上的资料并不齐全,这里完成后特地进行总结。

这里需要做到,例如收到Australia/Canberra后,需要得出对应时区的UTC偏移,然后更改系统时间,并且是需要适应冬夏令时的情况。
按照网上资料进行zoneinfo移植并设置时区后,发现时间并不对,后来查找资料发现uclibc和glibc对时区的使用有差异

1.对于uclibc,重要文件是/etc/TZ,实际连接到/tmp/TZ,修改时区后,会根据配置文件system中的timezone的option修改/tmp/TZ

2.对于glibc,重要文件是/etc/localtime,实际连接到/tmp/localtime,而/tmp/localtime也是连接文件,根据配置文件system中的zonename的option修改该连接

而我是uclibc,所以方法会更复杂些,glibc的话会更简单,因为在尝试的过程中都试了,所以一并总结下。

2.方案实现

最终逻辑为:交叉编译timezoneinfo数据库后进行tar.bz2的压缩,节约出flash空间,再放到目标板中,当拿到服务端传来的Asia/Shanghai后,解压数据库到内存中,完成时区信息匹配后,再将内存中的文件删除,达成目的。

数据库timezoneinfo其中记载了全球各个地区的时区信息,以及冬夏令时信息等。
其中有tzdata2024a.tar.gz和tzcode2024a.tar.gz,tzdata是时区信息的一个数据库,而tzcode是时区的命令以及用于生成数据库的工具,需要用其中的工具,在target上生成出时区数据库。下载地址https://www.iana.org/time-zones

2.1 下载源码、数据库

mkdir /tmp/zoneinfo
tar -vxf tzcode2024a.tar.gz -C /tmp/zoneinfo
tar -vxf tzdata2024a.tar.gz -C /tmp/zoneinfo

解压后大致内容如下:
image.png

2.2 编译源码

因为要移植到目标板上,所以先在虚拟机上make 并make install看下执行了哪些操作,再用交叉编译工具链编译,并安装到目标板上。

2.2.1 虚拟机上编译

make
make install

install时大概执行的内容如下:

make BACKWARD='backward'  DESTDIR=''  LEAPSECONDS=''  PACKRATDATA=''  PACKRATLIST=''  TZDEFAULT='/etc/localtime'  TZDIR='/usr/share/zoneinfo'  ZIC='./zic ' LEAPSECONDS= install_data
make[1]: Entering directory '/tmp/zoneinfo'
./zic  -d '/usr/share/zoneinfo'  tzdata.zi
make[1]: Leaving directory '/tmp/zoneinfo'
rm -fr '/usr/share/zoneinfo-posix'
ln -s 'zoneinfo' '/usr/share/zoneinfo-posix' || \
          make BACKWARD='backward'  DESTDIR=''  LEAPSECONDS=''  PACKRATDATA=''  PACKRATLIST=''  TZDEFAULT='/etc/localtime'  TZDIR='/usr/share/zoneinfo'  ZIC='./zic ' TZDIR='/usr/share/zoneinfo-posix' posix_only
make BACKWARD='backward'  DESTDIR=''  LEAPSECONDS=''  PACKRATDATA=''  PACKRATLIST=''  TZDEFAULT='/etc/localtime'  TZDIR='/usr/share/zoneinfo'  ZIC='./zic ' TZDIR='/usr/share/zoneinfo-leaps' right_only
make[1]: Entering directory '/tmp/zoneinfo'
make BACKWARD='backward'  DESTDIR=''  LEAPSECONDS=''  PACKRATDATA=''  PACKRATLIST=''  TZDEFAULT='/etc/localtime'  TZDIR='/usr/share/zoneinfo-leaps'  ZIC='./zic ' LEAPSECONDS='-L leapseconds' \
                install_data
make[2]: Entering directory '/tmp/zoneinfo'
./zic  -d '/usr/share/zoneinfo-leaps' -L leapseconds tzdata.zi
make[2]: Leaving directory '/tmp/zoneinfo'
make[1]: Leaving directory '/tmp/zoneinfo'
mkdir -p '/usr/bin' \
                '/usr/bin' '/usr/sbin' \
                '/usr/lib' \
                '/usr/share/man/man3' '/usr/share/man/man5' \
                '/usr/share/man/man8'
./zic  -d '/usr/share/zoneinfo'  -l Factory \
                `case '-' in ?*) echo '-p';; esac \
                ` - \
                -t '/etc/localtime'
cp -f iso3166.tab leapseconds tzdata.zi zone.tab zone1970.tab zonenow.tab '/usr/share/zoneinfo/.'
cp tzselect '/usr/bin/.'
cp zdump '/usr/bin/.'
cp zic '/usr/sbin/.'
cp libtz.a '/usr/lib/.'
: '/usr/lib/libtz.a'
cp -f newctime.3 newtzset.3 '/usr/share/man/man3/.'
cp -f tzfile.5 '/usr/share/man/man5/.'
cp -f tzselect.8 zdump.8 zic.8 '/usr/share/man/man8/.'

那么在移植到嵌入式板上的时候,也是直接模仿这个过程

直接虚拟机上测试下效果。

export TZDIR="/usr/share/zoneinfo"
export TZ="Australia/Canberra"
date -R

能看到时间显示为+11时区,修改成功
在这里插入图片描述

2.2.2 移植到开发板上

在目标机上创建两个文件夹,zoneinfo用来放源码文件,zoneinfo_data用来存放生成的时区数据库文件

cd /tmp
mkdir zoneinfo
mkdir zoneinfo_data

虚拟机上先make clean一下,然后重新开始编译

sudo make CC=/home/xzx/share/project_ipc/hm1002_in/code/openwrt2/staging_dir/toolchain-mipsel_24kec+dsp_gcc-11.2.0_uClibc-0.9.33.2/bin/mipsel-openwrt-linux-uclibc-gcc CFLAGS="-DHAVE_GETTEXT=0 -DHAVE_GETRANDOM=0"

-DHAVE_GETTEXT=0 -DHAVE_GETRANDOM=0 是为了解决编译报错,undefined reference to textdomain'以及undefined reference to dcgettext’问题。
编译通过后,将编译后的整个文件夹拷贝到目标板上的 /tmp/zoneinfo 上。

模仿虚拟机上的make install操作,进行时区数据库生成

./zic  -d '/tmp/zoneinfo_data/zoneinfo'  tzdata.zi
rm -fr '/tmp/zoneinfo_data/zoneinfo-posix'

ln -s '/tmp/zoneinfo_data/zoneinfo' '/tmp/zoneinfo_data/zoneinfo-posix'

./zic  -d '/tmp/zoneinfo_data/zoneinfo-leaps' -L leapseconds tzdata.zi

mkdir -p '/usr/bin' \
                '/usr/bin' '/usr/sbin' \
                '/usr/lib' \

./zic  -d '/tmp/zoneinfo_data/zoneinfo'  -l Factory \
                `case '-' in ?*) echo '-p';; esac \
                ` - \
                -t '/etc/localtime'

cp -f iso3166.tab leapseconds tzdata.zi zone.tab zone1970.tab zonenow.tab '/tmp/zoneinfo_data/zoneinfo/.'

# 这里先确认下自己的目标板环境中有没有/etc/localtime文件。
# 如果是uclibc+openwet的环境,没有/etc/localtime文件,下面的指令全部不需要执行了!!执行了也没有作用,反而会影响最终结果!
# 这里也是我自己踩了很久坑的地方!
rm /usr/bin/tzselect /usr/bin/zdump /usr/sbin/zic /usr/lib/libtz.a
ln -s /tmp/zoneinfo/tzselect '/usr/bin/.'
ln -s /tmp/zoneinfo/zdump '/usr/bin/.'
ln -s /tmp/zoneinfo/zic '/usr/sbin/.'
ln -s /tmp/zoneinfo/libtz.a '/usr/lib/.'
: '/usr/lib/libtz.a'

export TZDIR="/tmp/zoneinfo_data/zoneinfo"
export TZ="Asia/Shanghai"

如果是glibc环境,执行完上面的之后,输入date -R便能成功看到时间发生了变化,这里之后的操作便不需要继续执行了,成功完成了数据库的移植与使用!

而如果是uclibc+openwrt环境,不需要执行上面下部分的命令,通过vi /tmp/zoneinfo_data/zoneinfo/Australia/Canberra 能看到最后一行便是对应的POSIX时区信息,将他们设置到openwrt环境中。
image.png

设置为openwrt的系统时间:

uci set system.@system[0].timezone='AEST-10AEDT,M10.1.0,M4.1.0/3'
uci commit system
/etc/init.d/system restart

root@OpenWrt:/tmp/zoneinfo# date -R
Wed, 06 Mar 2024 19:25:57 +1100

可以看到系统时间发生了变化,并且时间正确

2.2.3 TZ的格式

TZ = local_timezone,date/time,date/time
local_timezone是时区名称,其后两个date/time分别表示DST变更时间点(即何时开始,何时结束),date格式为Mm.n.d(注:“M”是字符),其中m范围为1-12月份,如M3表示3月份;n范围为1-5,1表示一个月中第一周,5表示最后一周;d范围为0~6,0表示星期日,6表示星期六。time为hh:mm:ss的格式。

则AEST-10AEDT,M10.1.0,M4.1.0/3代表 AEST-10AEDT时区,从第十个月开始的第一周的星期天开始变更为夏令时,从第四个月的第一周的星期天3点钟结束

3.压缩数据库并使用

因为板子上的flash空间不足,所以决定以压缩包形式放入,待需要时再解压出来。如果没有这个需求的话,可以不用看。

1)数据库文件传回虚拟机进行压缩

scp * xzx@192.168.80.228:/tmp/zoneinfo_data/

这里我是在虚拟机上进行.tar.bz2压缩

tar -vcjf zoneinfo_data.tar.bz2 /tmp/zoneinfo_data

压缩前的zoneinfo_data大约2.8MB,压缩后的zoneinfo_data.tar.bz2在95KB左右

2)用程序解压压缩包,并设置时区
uclibc+openwrt可以参考一下代码

#include <stdio.h>
#include <bzlib.h>
#include <string>
#include <sys/ioctl.h>  
#include <sys/types.h>  
#include <stdarg.h>
#include <sys/time.h>
#include <signal.h>
#include<stdexcept>

bool linuxPopenExecCmd(std::string &strOutData, const char * pFormat, ...)
{
    char acBuff[128] ={0};

    va_list ap;
    va_start(ap, pFormat);
    vsprintf(acBuff, pFormat, ap);
    va_end(ap);

    try {
        FILE *pFile = popen(acBuff, "r");
        if (!pFile) {
            throw std::runtime_error("linuxPopenExecCmd popen() failed!");
        }

        char acValue[512] = {0};
        while (!feof(pFile)) {
            if (fgets(acValue, sizeof(acValue), pFile) != nullptr) {
                strOutData += acValue;
            }
        }
        pclose(pFile);
    }

    catch (const std::exception& e)
        {
            printf("popen :%s failed: %s", acBuff, e.what());
            return false;
        }
    return true;
}


int deCompress(const char *srcFile, const char *dstFile)
{
    int iRet = 0;
    FILE *fileInput = NULL;
    FILE *fileOutput = NULL;
    BZFILE *bzInput = NULL;

    int iBytesRead = 0;
    int iResult = 0;
    char acBuffer[1024] = {0};

    fileInput = fopen(srcFile, "rb");
    if (!fileInput) 
    {
        printf("error opening fileInput file\n");
        iRet = -1;
        goto exit;
    }

    fileOutput = fopen(dstFile, "wb");
    if (!fileOutput) 
    {
        printf("error opening fileOutput file\n");
        iRet = -1;
        goto exit;
    }

    bzInput = BZ2_bzReadOpen(NULL, fileInput, 0, 0, NULL, 0);
    if (!bzInput) 
    {
        printf("error read open file\n");
        iRet = -1;
        goto exit;
    }

    while (1) 
        {
            iBytesRead = BZ2_bzRead(&iResult, bzInput, acBuffer, sizeof(acBuffer));
            if (iBytesRead == 0)
            {
                printf("bz2 read successful\n");
                break;
            }
            if (iResult != BZ_OK && iResult != BZ_STREAM_END) 
            {
                printf("error reading bz2 data:%d\n", iResult);
                break;
            }
            fwrite(acBuffer, 1, iBytesRead, fileOutput);
        }

    BZ2_bzReadClose(&iResult, bzInput);
    if (iResult != BZ_OK) 
    {
        iRet = -1;
        goto exit;
    }

    printf("decompress successful. written to %s\n", dstFile);
    iRet = 0;
    exit:
    if (fileInput)
    {
        fclose(fileInput);
        fileInput = NULL;
    }
    if (fileOutput)
    {
        fclose(fileOutput);
        fileOutput = NULL;
    }
    return iRet;
}

int syncTimezone(const char *infoFile, const char *region)
{
    std::string strRegionPach;
    strRegionPach.append(infoFile);
    strRegionPach.append("/");
    strRegionPach.append(region);
    FILE* file = fopen(strRegionPach.c_str(), "r");

    if (file == NULL) 
    {
        printf("open failed: %s\n", strRegionPach.c_str());
        return -1;
    }
    printf("open success: %s\n", strRegionPach.c_str());

    char last_line[512] = {0};
    while (fgets(last_line, sizeof(last_line), file) != NULL) {
        printf("xxxxx line: %s\n", last_line);
        // 什么都不做,只需保留最后一行
    }

    fclose(file);

    printf("last line: %s\n", last_line);

    //uci set system.@system[0].timezone='AEST-10AEDT,M10.1.0,M4.1.0/3'
    std::string strValue;
    linuxPopenExecCmd(strValue, "uci set system.@system[0].timezone=%s", last_line);
	linuxPopenExecCmd(strValue, "uci commit system");
	linuxPopenExecCmd(strValue, "/etc/init.d/system restart");




	return 0;
}


int main(int argc, char** argv)
{
	int iRet = 0;
	const char *inputFile = "/usr/share/zoneinfo_data.tar.bz2";
	const char *deCompressFile = "/tmp/zoneinfo_data.tar";
	const char *outputFile = "/tmp/zoneinfo_data";

    iRet = deCompress(inputFile, deCompressFile);
	if (iRet < 0)
	{
		printf("decompress failed\n");
		return -1;
	}
	std::string strValue;
	linuxPopenExecCmd(strValue, "tar -vxf %s", deCompressFile);


	// syncTimezone(outputFile, "Australia/Canberra");
	syncTimezone(outputFile, "Asia/Shanghai");

	linuxPopenExecCmd(strValue, "rm -rf %s", deCompressFile);
	linuxPopenExecCmd(strValue, "rm -rf %s", outputFile);
	return 0;
}

这里我用的是bz2压缩,大家根据实际情况选择,替换代码即可,如果是glibc等使用/etc/localtime方式的话则最后是代码实现建立软连接到 /etc/localtime,例如ln -s /tmp/zoneinfo_data/zoneinfo/Australia/Canberra /etc/localtime

  • 16
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
OpenWrt 上使用 Valgrind 需要注意以下几点: 1. 安装 Valgrind 可以通过 opkg 安装 Valgrind: ``` opkg update opkg install valgrind ``` 2. 配置 Valgrind 默认情况下,Valgrind 会使用 glibc 库,而 OpenWrt 中使用的是 uClibc 库,因此需要手动配置 Valgrind。 首先,需要创建一个文件 `/etc/valgrindrc`,并添加以下内容: ``` # Valgrind configuration file for uClibc libc-libraries: /lib/libuClibc-*.so.* ``` 然后,在运行 Valgrind 时,需要指定使用该配置文件: ``` valgrind --tool=memcheck --vgdb=no --trace-children=yes --num-callers=20 --suppressions=/usr/lib/valgrind/uClibc.supp --read-var-info=yes --malloc-fill=0xFE --free-fill=0xEF --leak-check=full --show-reachable=yes --track-origins=yes --log-file=/tmp/valgrind.log --error-limit=no --undef-value-errors=no --gen-suppressions=all --fair-sched=yes --quiet --trace-children=yes --trace-children-skip=*dhclient* --trace-children-skip=*udhcpc* --trace-children-skip=*pppd* --trace-children-skip=*klogd* --trace-children-skip=*syslogd* --trace-children-skip=*hotplug2* --trace-children-skip=*ntpd* --trace-children-skip=*odhcpd* --trace-children-skip=*dnsmasq* --trace-children-skip=*hostapd* --trace-children-skip=*wpa_supplicant* --trace-children-skip=*ubusd* --trace-children-skip=*logd* --trace-children-skip=*smbd* --trace-children-skip=*nmbd* --trace-children-skip=*irqbalance* --trace-children-skip=*procd* --trace-children-skip=*crond* --trace-children-skip=*ubus* --trace-children-skip=*ubusd* --trace-children-skip=*uhttpd* --trace-children-skip=*amule* --trace-children-skip=*transmission* --trace-children-skip=*minidlna* --trace-children-skip=*mjpg_streamer* --trace-children-skip=*sshd* --trace-children-skip=*swapon* --trace-children-skip=*swapoff* --trace-children-skip=*fstab* --trace-children-skip=*mount* --trace-children-skip=*umount* --trace-children-skip=*tar* --trace-children-skip=*rsync* --trace-children-skip=*scp* --trace-children-skip=*sftp* --trace-children-skip=*ftpd* --trace-children-skip=*ftp* --trace-children-skip=*telnetd* --trace-children-skip=*ssh* --trace-children-skip=*tftp* --trace-children-skip=*httpd* --trace-children-skip=*vnstatd* --trace-children-skip=*ntfs-3g* --trace-children-skip=*samba* --trace-children-skip=*proftpd* --trace-children-skip=*lighttpd* --trace-children-skip=*php* --trace-children-skip=*mysql* --trace-children-skip=*sqlite3* --trace-children-skip=*redis* --trace-children-skip=*memcached* --trace-children-skip=*mosquitto* --trace-children-skip=*influxd* --trace-children-skip=*grafana-server* --trace-children-skip=*postgresql* --trace-children-skip=*mongodb* --trace-children-skip=*cupsd* --trace-children-skip=*dovecot* --trace-children-skip=*nginx* --trace-children-skip=*php-fpm* --trace-children-skip=*thttpd* --trace-children-skip=*dnscrypt-proxy* --trace-children-skip=*tor* --trace-children-skip=*tinyproxy* --trace-children-skip=*privoxy* --trace-children-skip=*squid* --trace-children-skip=*polipo* --trace-children-skip=*darkhttpd* --trace-children-skip=*kamailio* --trace-children-skip=*opensips* --trace-children-skip=*asterisk* --trace-children-skip=*freeswitch* --trace-children-skip=*nagios* --trace-children-skip=*nrpe* --trace-children-skip=*collectd* --trace-children-skip=*snmpd* --trace-children-skip=*openvpn* --trace-children-skip=*pptpd* --trace-children-skip=*strongswan* --trace-children-skip=*xl2tpd* --trace-children-skip=*pppoe-server* --trace-children-skip=*pppoe-relay* --trace-children-skip=*pppoe* --trace-children-skip=*ppp* --trace-children-skip=*rtorrent* --trace-children-skip=*transmission-daemon* --trace-children-skip=*darkstat* --trace-children-skip=*vnstat* --trace-children-skip=*iptraf-ng* --trace-children-skip=*tcpdump* --trace-children-skip=*wireshark* --trace-children-skip=*snort* --trace-children-skip=*sflowtool* --trace-children-skip=*sflow-rt* --trace-children-skip=*ntopng* --trace-children-skip=*openvswitch* --trace-children-skip=*kmod* --trace-children-skip=*iptables* --trace-children-skip=*ip6tables* --trace-children-skip=*ipset* --trace-children-skip=*ulogd* --trace-children-skip=*dhcp6c* --trace-children-skip=*dhcp6s* --trace-children-skip=*wide-dhcpv6* --trace-children-skip=*radvd* --trace-children-skip=*6relayd* --trace-children-skip=*odhcp6c* --trace-children-skip=*odhcpd-dhcpv6* --trace-children-skip=*ip6tables-save* --trace-children-skip=*ip6tables-restore* --trace-children-skip=*iptables-save* --trace-children-skip=*iptables-restore* --trace-children-skip=*ip6tables-restore* --trace-children-skip=*iptables-restore* --trace-children-skip=*logrotate* --trace-children-skip=*sysupgrade* --trace-children-skip=*jffs2dump* --trace-children-skip=*ubiformat* --trace-children-skip=*ubiupdatevol* --trace-children-skip=*ubiattach* --trace-children-skip=*ubidetach* --trace-children-skip=*ubimkvol* --trace-children-skip=*ubirmvol* --trace-children-skip=*ubirename* --trace-children-skip=*ubiupdatevol* --trace-children-skip=*ubiblock* --trace-children-skip=*ubinize* --trace-children-skip=*ubi* --trace-children-skip=*mtd* --trace-children-skip=*dd* --trace-children-skip=*fdisk* --trace-children-skip=*parted* --trace-children-skip=*mkfs* --trace-children-skip=*mkswap* --trace-children-skip=*mkfs.ext3* --trace-children-skip=*mkfs.ntfs* --trace-children-skip=*mkfs.vfat* --trace-children-skip=*mkfs.xfs* --trace-children-skip=*mkfs.jffs2* --trace-children-skip=*mkfs.ubifs* --trace-children-skip=*mount* --trace-children-skip=*umount* --trace-children-skip=*mount* --trace-children-skip=*umount* --trace-children-skip=*fsck* --trace-children-skip=*fsck.ext3* --trace-children-skip=*fsck.ntfs* --trace-children-skip=*fsck.vfat* --trace-children-skip=*fsck.xfs* --trace-children-skip=*fsck.jffs2* --trace-children-skip=*fsck.ubifs* --trace-children-skip=*e2label* --trace-children-skip=*ntfslabel* --trace-children-skip=*dosfslabel* --trace-children-skip=*xfs_admin* --trace-children-skip=*jffs2* --trace-children-skip=*mke2fs* --trace-children-skip=*ntfs-3g.probe* --trace-children-skip=*ntfs-3g.secaudit* --trace-children-skip=*ntfs-3g.usermap* --trace-children-skip=*ntfs-3g* --trace-children-skip=*mount.ntfs-3g* --trace-children-skip=*mount.ntfs* --trace-children-skip=*udhcpc* --trace-children-skip=*dhclient* --trace-children-skip=*dhcpd* --trace-children-skip=*dnsmasq* --trace-children-skip=*hostapd_cli* --trace-children-skip=*wpa_cli* --trace-children-skip=*wpa_supplicant* --trace-children-skip=*pppd* --trace-children-skip=*pptp* --trace-children-skip=*l2tpd* --trace-children-skip=*openconnect* --trace-children-skip=*openvpn* --trace-children-skip=*strongswan* --trace-children-skip=*xl2tpd* --trace-children-skip=*pppoe-server* --trace-children-skip=*pppoe-relay* --trace-children-skip=*pppoe* --trace-children-skip=*ppp* --trace-children-skip=*smbd* --trace-children-skip=*nmbd* --trace-children-skip=*nmblookup* --trace-children-skip=*smbclient* --trace-children-skip=*smbpasswd* --trace-children-skip=*smbstatus* --trace-children-skip=*smbtree* --trace-children-skip=*wins* --trace-children-skip=*samba-tool* --trace-children-skip=*transmission* --trace-children-skip=*transmission-daemon* --trace-children-skip=*amule* --trace-children-skip=*aria2c* --trace-children-skip=*wget* --trace-children-skip=*curl* --trace-children-skip=*ftp* --trace-children-skip=*scp* --trace-children-skip=*sftp* --trace-children-skip=*rsync* --trace-children-skip=*tar* --trace-children-skip=*tftp* --trace-children-skip=*telnet* --trace-children-skip=*ssh* --trace-children-skip=*sftp-server* --trace-children-skip=*ftp-proxy* --trace-children-skip=*proxsmtp* --trace-children-skip=*spamassassin* --trace-children-skip=*fetchmail* --trace-children-skip=*dovecot* --trace-children-skip=*postfix* --trace-children-skip=*exim* --trace-children-skip=*sendmail* --trace-children-skip=*nginx* --trace-children-skip=*apache2* --trace-children-skip=*lighttpd* --trace-children-skip=*php* --trace-children-skip=*mysql* --trace-children-skip=*postgresql* --trace-children-skip=*mosquitto* --trace-children-skip=*influxd* --trace-children-skip=*grafana-server* --trace-children-skip=*memcached* --trace-children-skip=*redis* --trace-children-skip=*mongodb* --trace-children-skip=*cupsd* --trace-children-skip=*darkhttpd* --trace-children-skip=*dnscrypt-proxy* --trace-children-skip=*tor* --trace-children-skip=*tinyproxy* --trace-children-skip=*privoxy* --trace-children-skip=*squid* --trace-children-skip=*polipo* --trace-children-skip=*kamailio* --trace-children-skip=*opensips* --trace-children-skip=*asterisk* --trace-children-skip=*freeswitch* --trace-children-skip=*nagios* --trace-children-skip=*nrpe* --trace-children-skip=*collectd* --trace-children-skip=*snmpd* --trace-children-skip=*openvswitch* --trace-children-skip=*iptables* --trace-children-skip=*ip6tables* --trace-children-skip=*ipset* --trace-children-skip=*ulogd* --trace-children-skip=*dhcp6c* --trace-children-skip=*dhcp6s* --trace-children-skip=*wide-dhcpv6* --trace-children-skip=*radvd* --trace-children-skip=*6relayd* --trace-children-skip=*odhcp6c* --trace-children-skip=*odhcpd-dhcpv6* --trace-children-skip=*ip6tables-save* --trace-children-skip=*ip6tables-restore* --trace-children-skip=*iptables-save* --trace-children-skip=*iptables-restore* --trace-children-skip=*ip6tables-restore* --trace-children-skip=*iptables-restore* --trace-children-skip=*logrotate* --trace-children-skip=*sysupgrade* --trace-children-skip=*opkg* ``` 这里的参数根据需求来调整。 3. 运行 Valgrind 使用 `valgrind` 命令即可运行 Valgrind,例如: ``` valgrind --tool=memcheck --leak-check=full myprogram arg1 arg2 ``` 这里的 `myprogram` 是需要测试的程序,`arg1`、`arg2` 是该程序的参数。 注意:Valgrind 会对程序的运行速度有一定的影响,因此在测试时需要对程序进行压力测试,以确保测试结果的准确性。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值