在新 OS 上编译时遗留代码提供核心转储
Legacy code giving core dump when compiled on new OS
我正在处理遗留 c/c++ 项目。该项目最初是在 UNIX 上,然后他们在多年前迁移到 Linux。
现在,我们升级到 RHEL 7.9。自从我们升级后,我们用新的依赖库编译了所有旧代码。
该代码具有以下内容...
#include <pwd.h>
...
{
struct passwd *pwd;
...
...
// U2L commented for skiping ACMgetpwuid
// if ((pwd = ACMgetpwuid(primuid)) == NULL)
...
if (strlen_u2l(pwd->pw_passwd) == 0) {
...
}
此代码仍在生产中,它是 运行 RHEL 7 并且工作正常(我相信他们在 RHEL 5 上编译,同样在 RHEL 7 上运行并且工作正常)。如您所见,他们没有分配任何内存,也忘记了 if
块的注释,他们正在访问 pwd->pw_passwd
。
但是当我们现在在新的 RHEL 7 上编译相同的代码时,相同的代码正在提供核心转储。
为什么相同的代码在 RHEL 7 上编译时会产生核心转储?
但是旧的编译二进制文件(在 RHEL 5 上编译)没有在 RHEL 7 上提供核心转储。我是 UB 的受害者吗?
由于通过未初始化的指针取消引用,您是 undefined behavior 的受害者。
看来注释掉 pwd = ACMgetpwuid(primuid)
的人破坏了后面的代码。至少他们应该注释掉两个 if
语句。
pwd
是未初始化的,所以它的值是不确定的;它可以取决于堆栈上或某个寄存器中的先前字节。先前的值是什么可以取决于 OS、编译器版本、使用的编译标志、当前程序状态,即几乎任何东西。
有些编译器甚至省略了指向 UB 的整个代码段(如 if (strlen_u2l(pwd->pw_passwd) == 0)
),甚至不屑于为此类函数发出 return 指令。
我正在处理遗留 c/c++ 项目。该项目最初是在 UNIX 上,然后他们在多年前迁移到 Linux。 现在,我们升级到 RHEL 7.9。自从我们升级后,我们用新的依赖库编译了所有旧代码。 该代码具有以下内容...
#include <pwd.h>
...
{
struct passwd *pwd;
...
...
// U2L commented for skiping ACMgetpwuid
// if ((pwd = ACMgetpwuid(primuid)) == NULL)
...
if (strlen_u2l(pwd->pw_passwd) == 0) {
...
}
此代码仍在生产中,它是 运行 RHEL 7 并且工作正常(我相信他们在 RHEL 5 上编译,同样在 RHEL 7 上运行并且工作正常)。如您所见,他们没有分配任何内存,也忘记了 if
块的注释,他们正在访问 pwd->pw_passwd
。
但是当我们现在在新的 RHEL 7 上编译相同的代码时,相同的代码正在提供核心转储。
为什么相同的代码在 RHEL 7 上编译时会产生核心转储? 但是旧的编译二进制文件(在 RHEL 5 上编译)没有在 RHEL 7 上提供核心转储。我是 UB 的受害者吗?
由于通过未初始化的指针取消引用,您是 undefined behavior 的受害者。
看来注释掉 pwd = ACMgetpwuid(primuid)
的人破坏了后面的代码。至少他们应该注释掉两个 if
语句。
pwd
是未初始化的,所以它的值是不确定的;它可以取决于堆栈上或某个寄存器中的先前字节。先前的值是什么可以取决于 OS、编译器版本、使用的编译标志、当前程序状态,即几乎任何东西。
有些编译器甚至省略了指向 UB 的整个代码段(如 if (strlen_u2l(pwd->pw_passwd) == 0)
),甚至不屑于为此类函数发出 return 指令。