PMunch / futhark

Automatic wrapping of C headers in Nim
MIT License
394 stars 22 forks source link

size is not correct on struct_kinfo_proc from sys/sysctl.h #115

Closed inv2004 closed 3 months ago

inv2004 commented 3 months ago

nim-c-code:

  {.emit: """
#include <stdio.h>
#include <sys/sysctl.h>
""".}

  proc f() =
    {.emit: """
    printf("sz=%d\n", sizeof(struct kinfo_proc));
""".}
  f()
# sz=648

nim-code:

import futhark

importc:
  path: "/Library/Developer/CommandLineTools/SDKs/MacOSX14.4.sdk/usr/include"
  "sys/sysctl.h"

echo "sz = ", sizeof(struct_kinfo_proc)
# sz = 656

Do you know what could be the reason? Thank you

inv2004 commented 3 months ago

additional info: 8 bytes diff is on extern_proc from sys/proc.h

PMunch commented 3 months ago

Hmm, sysctl is deprecated and removed from glibc. Unfortunately this means I don't have the header on my machine so I can't really debug this. Wild guess though is that those two builds end up linking against a slightly different version of sys/sysctl.h, or that it's some GCC/Clang difference.

inv2004 commented 3 months ago

I was trying to use it on my mac. Let me try to extract minimal headers/structs

inv2004 commented 3 months ago
#define MAXCOMLEN       16

typedef int                     __int32_t;

typedef int             boolean_t;
typedef long                    __darwin_time_t;
typedef __int32_t       __darwin_suseconds_t;
typedef char *          caddr_t;
typedef unsigned int    u_int;

typedef unsigned int            u_int32_t;
typedef u_int32_t               fixpt_t;

typedef unsigned long long      u_int64_t;
typedef u_int64_t               u_quad_t;

typedef unsigned int            __uint32_t;
typedef __uint32_t      __darwin_sigset_t; 
typedef __darwin_sigset_t               sigset_t;

typedef unsigned char   u_char;

typedef __int32_t       __darwin_pid_t;
typedef __darwin_pid_t        pid_t;

struct timeval
{
    __darwin_time_t         tv_sec;         /* seconds */
    __darwin_suseconds_t    tv_usec;        /* and microseconds */
};

struct  itimerval {
    struct  timeval it_interval;    /* timer interval */
    struct  timeval it_value;       /* current value */
};

/* Exported fields for kern sysctls */
struct extern_proc4 {
    union {
        struct {
            struct  proc *__p_forw; /* Doubly-linked run/sleep queue. */
            struct  proc *__p_back;
        } p_st1;
        struct timeval __p_starttime;   /* process start time */
    } p_un;
    struct  vmspace *p_vmspace;     /* Address space. */
    struct  sigacts *p_sigacts;     /* Signal actions, state (PROC ONLY). */
    int     p_flag;                 /* P_* flags. */
    char    p_stat;                 /* S* process status. */
    pid_t   p_pid;                  /* Process identifier. */
    pid_t   p_oppid;         /* Save parent pid during ptrace. XXX */
    int     p_dupfd;         /* Sideways return value from fdopen. XXX */
    /* Mach related  */
    caddr_t user_stack;     /* where user stack was allocated */
    void    *exit_thread;   /* XXX Which thread is exiting? */
    int             p_debugger;             /* allow to debug */
    boolean_t       sigwait;        /* indication to suspend */
    /* scheduling */
    u_int   p_estcpu;        /* Time averaged value of p_cpticks. */
    int     p_cpticks;       /* Ticks of cpu time. */
    fixpt_t p_pctcpu;        /* %cpu for this process during p_swtime */
    void    *p_wchan;        /* Sleep address. */
    char    *p_wmesg;        /* Reason for sleep. */
    u_int   p_swtime;        /* Time swapped in or out. */
    u_int   p_slptime;       /* Time since last blocked. */
};
inv2004 commented 3 months ago
struct extern_proc4 {
    u_int   p_swtime;        /* Time swapped in or out. */
    u_int   p_slptime;       /* Time since last blocked. */
};
sz = 8
sz = 16

--added-- I am not sure, but my assumption that the u_int from .h file classified like nim's uint

--added-- rename "u_int", "u_intt" helps. Not sure if futhark should handle it or not

PMunch commented 3 months ago

Aha! Wow that's an inconvenient bug, and hard to catch.

In 0.13.3 I've added a warning for when overridden types don't match in size, that should make these errors easier to catch in the future. I've also added a collision check for all the types in system.nim, so u_int now gets renamed so it doesn't collide with uint.

This last fix should mean that your code now works out of the box. Please try the code again and check.

PMunch commented 3 months ago

Did you ever get this tested?

inv2004 commented 3 months ago

I changed my work macbook to lenovo. But if I remember correct it worked with simple example.

Thank you