数据库内核月报 - 2015 / 09-PgSQL · 答疑解惑 · 诡异的函数返回值

背景

修改PG源码时,在elog.c文件中准备调用timestamp.c中的TimestampTz GetCurrentTimestamp(void),以获取当前时间,TimestampTz是个int64类型,但是返回值类型不是期望的(是个int32值),但是在另外一个文件postgres.c调用返回的是正常的,如下:

elog.c: GetCurrentTimestamp() = 3891376011
postgres.c: GetCurrentTimestamp() = 495621643471576

也就是说,同一个函数在不同文件返回值的长度完全不同!

原因调查

首先查看具体函数定义GetCurrentTimestamp(),怀疑是elog.c没有宏定义HAVE_INT64_TIMESTAMP,随后gdb调试查看,最终计算的结果result确实是int64的值,当这个函数返回之后得到的值却变成了int32的值。

TimestampTz
GetCurrentTimestamp(void)
{
	TimestampTz result;
	struct timeval tp;

	gettimeofday(&tp, NULL);

	result = (TimestampTz) tp.tv_sec -
		((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY);

#ifdef HAVE_INT64_TIMESTAMP
	result = (result * USECS_PER_SEC) + tp.tv_usec;
#else
	result = result + (tp.tv_usec / 1000000.0);
#endif

	return result;
}

难道elog.c调用的不是timestamp.c中这个函数?继续在源码中查找这个GetCurrentTimestamp函数定义,看是否有多个定义。但是查找的结果是除了这个文件有定义,其他文件都没有这个函数定义,并且在timestamp.c这个函数中添加debug信息也都打印出来了,现在可以确定是函数返回的时候将int64转成int32了。百思不得其解之际,最后在编译日志中发现一个warning:

elog.c:2245: warning: implicit declaration of function ‘GetCurrentTimestamp’

在网上搜了一下,这种警告是由于函数未声明引起的,但是GetCurrentTimestamp()在timestamp.h中声明了,通过对比postgres.c和elog.c include的头文件发现区别:postgres.c包含#include "utils/timestamp.h",也就是在postgres.c 中含有GetCurrentTimestamp的函数声明,而在elog.c中却没有。在通过测试发现,C程序如果在函数调用前,没有对函数作声明,则编译系统会把第一次遇到的该函数形式(函数定义或函数调用)作为函数的声明,并将函数类型默认为int 型!

解决方法

在elog.c中添加#include "utils/timestamp.h"头文件,并查看编译日志看是否有其他这样的warning。重新配置编译选项,加上-Werror-implicit-function-declaration,将这种warning改成error,提前报错。

总结

对于这个warning需要重视,通过修改编译选项将其变成error,便于我们发现问题,错误发现的越早越好,避免在编译时忽略或者掩盖错误。如果不是这个函数返回值错误特别明显,它将有可能成为一个隐形的bug。

时间: 2024-09-27 10:56:18

数据库内核月报 - 2015 / 09-PgSQL · 答疑解惑 · 诡异的函数返回值的相关文章

阿里数据库内核月报:2015年09月

# 01 MySQL · 引擎特性 · InnoDB Adaptive hash index介绍 # 02 PgSQL · 特性分析 · clog异步提交一致性.原子操作与fsync # 03 MySQL · 捉虫动态 · BUG 几例 # 04 PgSQL · 答疑解惑 · 诡异的函数返回值 # 05 MySQL · 捉虫动态 · 建表过程中crash造成重建表失败 # 06 PgSQL · 特性分析 · 谈谈checkpoint的调度 # 07 MySQL · 特性分析 · 5.6 并行复制

阿里数据库内核月报:2015年11月

# 01 MySQL · 社区见闻 · OOW 2015 总结 MySQL 篇 # 02 MySQL · 特性分析 · Statement Digest # 03 PgSQL · 答疑解惑 · PostgreSQL 用户组权限管理 # 04 MySQL · 特性分析 · MDL 实现分析 # 05 PgSQL · 特性分析 · full page write 机制 # 06 MySQL · 捉虫动态 · MySQL 外键异常分析 # 07 MySQL · 答疑解惑 · MySQL 优化器 ran

阿里数据库内核月报:2015年08月

# 01 MySQL · 社区动态 · InnoDB Page Compression # 02 PgSQL · 答疑解惑 · RDS中的PostgreSQL备库延迟原因分析 # 03 MySQL · 社区动态 · MySQL5.6.26 Release Note解读 # 04 PgSQL · 捉虫动态 · 执行大SQL语句提示无效的内存申请大小 # 05 MySQL · 社区动态 · MariaDB InnoDB表空间碎片整理 # 06 PgSQL · 答疑解惑 · 归档进程cp命令的core

阿里数据库内核月报:2015年12月

# 01 MySQL · 引擎特性 · InnoDB 事务子系统介绍 # 02 PgSQL · 特性介绍 · 全文搜索介绍 # 03 MongoDB · 捉虫动态 · Kill Hang问题排查记录 # 04 MySQL · 参数优化 ·RDS MySQL参数调优最佳实践 # 05 PgSQL · 特性分析 · 备库激活过程分析 # 06 MySQL · TokuDB · 让Hot Backup更完美 # 07 PgSQL · 答疑解惑 · 表膨胀 # 08 MySQL · 特性分析 · Ind

阿里数据库内核月报合辑

阿里数据库内核月报:2017年05月 阿里数据库内核月报:2017年04月 阿里数据库内核月报:2017年03月 阿里数据库内核月报:2017年02月 阿里数据库内核月报:2017年01月 阿里数据库内核月报:2016年12月 阿里数据库内核月报:2016年11月 阿里数据库内核月报:2016年10月 阿里数据库内核月报:2016年09月 阿里数据库内核月报:2016年08月 阿里数据库内核月报:2016年07月 阿里数据库内核月报:2016年06月 阿里数据库内核月报:2016年05月 阿里数

阿里数据库内核月报:2016年03月

# 01 MySQL · TokuDB · 事务子系统和 MVCC 实现 # 02 MongoDB · 特性分析 · MMAPv1 存储引擎原理 # 03 PgSQL · 源码分析 · 优化器逻辑推理 # 04 SQLServer · BUG分析 · Agent 链接泄露分析 # 05 Redis · 特性分析 · AOF Rewrite 分析 # 06 MySQL · BUG分析 · Rename table 死锁分析 # 07 MySQL · 物理备份 · Percona XtraBacku

阿里数据库内核月报:2015年05月

# 01 MySQL · 引擎特性 · InnoDB redo log漫游 # 02 MySQL · 专家投稿 · MySQL数据库SYS CPU高的可能性分析 # 03 MySQL · 捉虫动态 · 5.6 与 5.5 InnoDB 不兼容导致 crash # 04 MySQL · 答疑解惑 · InnoDB 预读 VS Oracle 多块读 # 05 PgSQL · 社区动态 · 9.5 新功能BRIN索引 # 06 MySQL · 捉虫动态 · MySQL DDL BUG # 07 MyS

阿里数据库内核月报:2015年07月

# 01 MySQL · 引擎特性 · Innodb change buffer介绍 # 02 MySQL · TokuDB · TokuDB Checkpoint机制 # 03 PgSQL · 特性分析 · 时间线解析 # 04 PgSQL · 功能分析 · PostGIS 在 O2O应用中的优势 # 05 MySQL · 引擎特性 · InnoDB index lock前世今生 # 06 MySQL · 社区动态 · MySQL内存分配支持NUMA # 07 MySQL · 答疑解惑 · 外

阿里数据库内核月报:2015年06月

# 01 MySQL · 引擎特性 · InnoDB 崩溃恢复过程 # 02 MySQL · 捉虫动态 · 唯一键约束失效 # 03 MySQL · 捉虫动态 · ALTER IGNORE TABLE导致主备不一致 # 04 MySQL · 答疑解惑 · MySQL Sort 分页 # 05 MySQL · 答疑解惑 · binlog event 中的 error code # 06 PgSQL · 功能分析 · Listen/Notify 功能 # 07 MySQL · 捉虫动态 · 任性的