www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Syscall wrapper and stack destruction

reply Eugene V. <tech.vindex gmail.com> writes:
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
parent Eugene V. <tech.vindex gmail.com> writes:
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