Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

syscall: use prlimit64, not prlimit #2492

Closed
hanwen opened this issue Nov 23, 2011 · 12 comments
Closed

syscall: use prlimit64, not prlimit #2492

hanwen opened this issue Nov 23, 2011 · 12 comments

Comments

@hanwen
Copy link
Contributor

hanwen commented Nov 23, 2011

Rlimit.Cur/Max should be declared as uint, not uint64. I'm on weekly 2011-11-18

/usr/include/linux/resource.h 
struct rlimit {
        unsigned long   rlim_cur;
        unsigned long   rlim_max;
};

on 386:

#include <sys/resource.h>
#include <stdio.h>
int main() {
  struct rlimit rl;
  getrlimit(RLIMIT_NOFILE, &rl);
  printf("sz %d c %d m %d", sizeof(rl.rlim_cur), rl.rlim_cur, rl.rlim_max);
}

=>

sz 4 c 1024 m 4096


8g however, 



package main
import (
    "syscall"
    "fmt"
    "unsafe"
)
const RLIMIT_NOFILE = 7
func main() {
    lim := syscall.Rlimit{}
    syscall.Getrlimit(RLIMIT_NOFILE, &lim)
    fmt.Printf("sz %d c %d m %d", unsafe.Sizeof(lim.Cur),
        lim.Cur, lim.Max)
}
=>
sz 8 c 17592186045440 m 0
@hanwen
Copy link
Contributor Author

hanwen commented Nov 23, 2011

Comment 1:

btw - I could try whip-up a test to check that for sizes of all datatypes.  IIRC, this
is the second error of this kind I've encountered so far.

@adg
Copy link
Contributor

adg commented Nov 23, 2011

Comment 2:

The Rlimit struct is provided by
  src/pkg/syscall/ztypes_$GOOS_$GOARCH.go
that is generated with
  cgo -godefs types_linux.go
It's possible that this was done on a 64-bit Linux machine or a machine with the
different headers to yours. I'm not sure how that would have happened. Can you try
regenerating ztypes_linux_386.go on your machine and tell us what the diff is?

Owner changed to @adg.

Status changed to WaitingForReply.

@hanwen
Copy link
Contributor Author

hanwen commented Nov 23, 2011

Comment 3:

I'll have a look. I run fedora on this machine though, so the last time I tried, there
were a lot of spurious differences due to the go stuff being run on a ubuntu lucid.

@hanwen
Copy link
Contributor Author

hanwen commented Nov 23, 2011

Comment 4:

a bug in cgo?
$   cgo -godefs types_linux.go|grep -C3 Rlimit
    Nivcsw      int32
}
type Rlimit struct {
    Cur uint64
    Max uint64
}
[hanwen@haring syscall]$ uname -a
Linux haring 3.1.1-2.fc16.i686 #1 SMP Mon Nov 14 16:16:34 UTC 2011 i686 i686 i386
GNU/Linux

@hanwen
Copy link
Contributor Author

hanwen commented Nov 23, 2011

Comment 5:

there is a rlimit and rlimit64, 
struct rlimit
  {
    rlim_t rlim_cur;
    rlim_t rlim_max;
  };
struct rlimit64
  {
    rlim64_t rlim_cur;
    rlim64_t rlim_max;
 };
with accompanying syscalls, 
extern int getrlimit (__rlimit_resource_t __resource, struct rlimit *__rlimits) __asm__
("" "getrlimit64") __attribute__ ((__nothrow__))
extern int getrlimit64 (__rlimit_resource_t __resource,
   struct rlimit64 *__rlimits) __attribute__ ((__nothrow__));
could it be that cgo matches the 64 bit type to the 32bit call?

@hanwen
Copy link
Contributor Author

hanwen commented Nov 23, 2011

Comment 6:

strace on C version:
getrlimit(RLIMIT_NOFILE, {rlim_cur=1024, rlim_max=4*1024}) = 0
strace on Go version:
old_getrlimit(RLIMIT_NOFILE, {rlim_cur=1024, rlim_max=4*1024}) = 0

@hanwen
Copy link
Contributor Author

hanwen commented Nov 25, 2011

Comment 8:

and here is the header of types_linux.go expanded with gcc -E

Attachments:

  1. expand.c.gz (27923 bytes)

@rsc
Copy link
Contributor

rsc commented Dec 9, 2011

Comment 9:

Labels changed: added priority-later.

@hanwen
Copy link
Contributor Author

hanwen commented Dec 14, 2011

Comment 10:

I did some more digging.
The problem is that the Go types_linux.go defines: 
#define _FILE_OFFSET_BITS 64
this causes the source to be compiled with 64 bits rlim_t; the getrlimit() call is then
aliased to prlimit() (strace identifies it as prlimit64).
The correct solution is to implement Go's Getrlimit on Linux in terms of SYS_PRLIMIT64
How does one do that in the source code of the syscall package?

@rsc
Copy link
Contributor

rsc commented Dec 14, 2011

Comment 11:

If it is just a matter of calling a different syscall (no parameters
change), then change
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
to
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error) = SYS_PRLIMIT64
and run mkall.sh -syscalls.  If you need to do some kind of conversion
of the arguments, delete that line, add
//sysnb prlimit64(whatever) (err error)
run mkall.sh -syscalls, and then edit syscall_linux.go to define func Getrlimit
in terms of prlimit64.
Russ

@rsc
Copy link
Contributor

rsc commented Jan 29, 2012

Comment 12:

Status changed to Accepted.

@bradfitz
Copy link
Contributor

bradfitz commented Jul 3, 2012

Comment 13:

This issue was closed by revision 8b7d39e.

Status changed to Fixed.

@golang golang locked and limited conversation to collaborators Jun 24, 2016
@rsc rsc unassigned adg Jun 22, 2022
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants