6 days ago

I wrote statx (Linux system call) wrapper and program to check.

import std.string, std.stdio;
import core.sys.posix.fcntl;

extern(C)
struct timestamp_t {
    long tv_sec;
    uint tv_nsec;
}

extern(C)
struct statx_t {
   uint stx_mask;
   uint stx_blksize;
   ulong stx_attributes;
   uint stx_nlink;
   uint stx_uid;
   uint stx_gid;
   ushort stx_mode;
   ulong stx_ino;
   ulong stx_size;
   ulong stx_blocks;
   ulong stx_attributes_mask;
   timestamp_t stx_atime;
   timestamp_t stx_btime;
   timestamp_t stx_ctime;
   timestamp_t stx_mtime;
   uint stx_rdev_major;
   uint stx_rdev_minor;
   uint stx_dev_major;
   uint stx_dev_minor;
}

extern(C)
int statx(int dfd,
          const char* filename,
          int flags,
          uint mask,
          statx_t* statxbuf);

enum STATX_BASIC_STATS = 0x000007ffU;
enum STATX_BTIME       = 0x00000800U;

enum STATX_DEFAULT = STATX_BASIC_STATS | STATX_BTIME;


statx_t specialStatX(string filepath) {
    int atflag = AT_SYMLINK_NOFOLLOW;
    statx_t stx;
    const char* p = toStringz(filepath);
    auto ret = statx(AT_FDCWD, p, atflag, STATX_DEFAULT, &stx);
    return stx;
}


void main() {
    statx_t stx = specialStatX("/usr/bin/");
    writeln(stx);
}

I see the output of the contents of the structure and segmentation fault.

$ ./statx_exp
statx_t(8191, 4096, 0, 2, 0, 0, 16877, 5242882, 135168, 272, 3160180, timestamp_t(1626714759, 723086062), timestamp_t(1615500156, 433375874), timestamp_t(1626596984, 824714693), timestamp_t(1626596984, 824714693), 0, 0, 8, 1)
Segmentation fault

Probably calling this function causes some mysterious stack destruction.
GDB shows:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()

My wrapper:

extern(C)
int statx(int dfd, const char* filename, int flags, uint mask, statx_t* statxbuf);

Origin (man statx):

int statx(int dirfd, const char *pathname, int flags,
          unsigned int mask, struct statx *statxbuf);

Structures, it seems, are also described correctly.
The problem manifests itself with all three compilers.

6 days ago

The real structure is different from the documented one. The problem was the difference in the size of the structures. The issue has been resolved.

extern(C)
struct statx_t {
   // 0x00
   uint stx_mask;
   uint stx_blksize;
   ulong stx_attributes;
   // 0x10
   uint stx_nlink;
   uint stx_uid;
   uint stx_gid;
   ushort stx_mode;
   ushort[1] __spare0;
   // 0x20
   ulong stx_ino;
   ulong stx_size;
   ulong stx_blocks;
   ulong stx_attributes_mask;
   // 0x40
   timestamp_t stx_atime;
   timestamp_t stx_btime;
   timestamp_t stx_ctime;
   timestamp_t stx_mtime;
   // 0x80
   uint stx_rdev_major;
   uint stx_rdev_minor;
   uint stx_dev_major;
   uint stx_dev_minor;
   /* // 0x90 */
   ulong stx_mnt_id;
   ulong __spare2;
   // 0xA0
   ulong[12] __spare3;	// Spare space for future expansion
}