digitalmars.D.learn - Syscall wrapper and stack destruction
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.
Jul 19 2021
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 } ```
Jul 19 2021