This is sources Bugzilla
Bugzilla Version 2.17.5
Bugzilla Bug 5245
  pthread_create returns ENOMEM instead of EAGAIN Last modified: 2007-11-08 17:25
     Query page      Enter new bug
Bug#: 5245   Hardware:   Reporter: wang fang <wangf@cn.fujitsu.com>
Host: Target: Build:
Product:     Add CC:
Component:   Version:   CC:
Remove selected CCs
Status: RESOLVED   Priority:  
Resolution: FIXED   Severity:  
Assigned To: Ulrich Drepper <drepper@redhat.com>   Target Milestone:  
Flags: Requestee:
  backport ()
  examined ()
  testsuite ()
Summary:
Keywords:

Attachment Description Type Created Actions
patch.txt patch to fix the bug patch 2007-11-02 03:47 Edit | Diff
Create a New Attachment (proposed patch, testcase, etc.) View All

Bug 5245 depends on: Show dependency tree
Show dependency graph
Bug 5245 blocks:

Additional Comments:


Leave as RESOLVED FIXED
Reopen bug
Mark bug as VERIFIED

View Bug Activity   |   Format For Printing


Description:   Last confirmed: 0000-00-00 00:00 Opened: 2007-11-02 03:43
I found a bug about the return value of pthread_create. The posix expects 
EAGAIN for lack of memory, but in fact, it returns ENOMEM.

This problem can be reproduced by the following code:
--------------------------------------------------------------------
#include <stdio.h>
#include <sys/mman.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>

void use_up_memory(void)
{
  char *c;
  int PAGESIZE = getpagesize();
  while (1) {
    c = mmap(NULL, PAGESIZE, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0);
    if (c == MAP_FAILED)
      break;
  }
  printf("errno %d: %s\n", errno, strerror(errno));
}

void child()
{
  sleep(1);
}

int main(int argc, char *argv[])
{
  int err;
  pthread_t tid;

  use_up_memory();

  err = pthread_create(&tid, NULL, (void *)child, NULL);
  if (err) {
    printf("pthread_cretate returns %d: %s\n", err, strerror(err));
    return 1;
  }

  err = pthread_join(tid, NULL);
  if (err){
    printf("pthread_join returns %d\n", err);
    return 1;
  }
  return 0;
}
--------------------------------------------------------------------


The result is as follows:

----------------------------------------------------------
$ ./test_pthread_create
errno 12: Cannot allocate memory
pthread_cretate returns 12: Cannot allocate memory
----------------------------------------------------------

------- Additional Comment #1 From wang fang 2007-11-02 03:47 -------
Created an attachment (id=2073)
patch to fix the bug

------- Additional Comment #2 From wang fang 2007-11-02 03:49 -------
This is tested with glibc version 2.7.

And the attached patch fixes the bug.

After applying the patch, the test result is:

-----------------------------------------------------------
$ ./test_pthread_create
errno 12: Cannot allocate memory
pthread_cretate returns 11: Resource temporarily unavailable
-----------------------------------------------------------

------- Additional Comment #3 From Ulrich Drepper 2007-11-08 00:44 -------
Fixed in cvs trunk but noth with the patch you provided.

------- Additional Comment #4 From wang fang 2007-11-08 01:07 -------
pthread_create() calls the static function creat_thread(), and this funciton 
at last calls __clone(), __clone() may set errno to ENOMEM. So why not check 
the ENOMEM in pthread_create(), it won't miss any ENOMEM case.

------- Additional Comment #5 From Ulrich Drepper 2007-11-08 17:25 -------
(In reply to comment #4)
> So why not check 
> the ENOMEM in pthread_create(), it won't miss any ENOMEM case.

Because unlike crappy proprietary software we don't settle for garbage.

     Query page      Enter new bug
Actions: New | Query | bug # | Reports | Requests   New Account | Log In