Skip to contentSkip to conversation

oslib: make error handling more reasonable

PATCH Superseded Zhi Yong Wu 9 participants 18 messages Feb 10, 2012 – Feb 14, 2012

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 oslib: make error handling more reasonable

From: Zhi Yong Wu <[email protected]>

---
 oslib-posix.c |    4 ++--
 oslib-win32.c |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
oslib-posix.c +2 -2
index b6a3c7f..f978d56 100644
@@ -80,7 +80,7 @@ void *qemu_oom_check(void *ptr)
 {
     if (ptr == NULL) {
         fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno));
-        abort();
+        exit(EXIT_FAILURE);
     }
     return ptr;
 }
@@ -94,7 +94,7 @@ void *qemu_memalign(size_t alignment, size_t size)
     if (ret != 0) {
         fprintf(stderr, "Failed to allocate %zu B: %s\n",
                 size, strerror(ret));
-        abort();
+        exit(EXIT_FAILURE);
     }
 #elif defined(CONFIG_BSD)
     ptr = qemu_oom_check(valloc(size));
oslib-win32.c +2 -2
index ce3021e..af2ff93 100644
@@ -35,7 +35,7 @@ void *qemu_oom_check(void *ptr)
 {
     if (ptr == NULL) {
         fprintf(stderr, "Failed to allocate memory: %lu\n", GetLastError());
-        abort();
+        exit(EXIT_FAILURE);
     }
     return ptr;
 }
@@ -45,7 +45,7 @@ void *qemu_memalign(size_t alignment, size_t size)
     void *ptr;
 
     if (!size) {
-        abort();
+        exit(EXIT_FAILURE);
     }
     ptr = qemu_oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
     trace_qemu_memalign(alignment, size, ptr);
Signature · 1 line
1.7.6
#1 lore raw
Quoted 13 lines · Zhi Yong Wu

From: Zhi Yong Wu <[email protected]>

---
 oslib-posix.c |    4 ++--
 oslib-win32.c |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
oslib-posix.c +0 -0
index b6a3c7f..f978d56 100644

oslib-posix.c void *qemu_oom_check(void *ptr) · line 83

Quoted 5 lines
oslib-posix.c +1 -1
@@ -80,7 +80,7 @@ void *qemu_oom_check(void *ptr)
 {
     if (ptr == NULL) {
         fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno));
-        abort();
+        exit(EXIT_FAILURE);

exit() will call any atexit()/on_exit() handlers, as well as trying to flush I/O streams. Any of these actions may require further memory allocations, which will likely fail, or worse cause this code to re-enter itself if an atexit() handler calls qemu_malloc

The only option other than abort(), is to use _Exit() which doesn't try to run cleanup handlers.

Daniel

Signature · 4 lines
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|
#2 lore raw
Quoted 9 lines · Daniel P. Berrange
Quoted 8 lines · Zhi Yong Wu

From: Zhi Yong Wu <[email protected]>

---
 oslib-posix.c |    4 ++--
 oslib-win32.c |    4 ++--

 2 files changed, 4 insertions(+), 4 deletions(-)
Quoted 15 lines

oslib-posix.c void *qemu_oom_check(void *ptr) · line 83

Quoted 10 lines
oslib-posix.c +1 -1
index b6a3c7f..f978d56 100644
@@ -80,7 +80,7 @@ void *qemu_oom_check(void *ptr)
  {
      if (ptr == NULL) {
          fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno));
-        abort();
+        exit(EXIT_FAILURE);

exit() will call any atexit()/on_exit() handlers, as well as trying to flush I/O streams. Any of these actions may require further memory allocations, which will likely fail, or worse cause this code to re-enter itself if an atexit() handler calls qemu_malloc

Nice, very reasonable.

Quoted 3 lines

The only option other than abort(), is to use  _Exit() which doesn't try to run cleanup handlers.

I will try to send out v2

Quoted 7 lines

Daniel
--

|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|
Signature · 3 lines
Regards,

Zhi Yong Wu
#3 lore raw

Am 10.02.2012 16:13, schrieb Zhi Yong Wu:

Quoted 27 lines
Quoted 9 lines · Daniel P. Berrange
Quoted 8 lines · Zhi Yong Wu

From: Zhi Yong Wu <[email protected]>

---
 oslib-posix.c |    4 ++--
 oslib-win32.c |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
Quoted 16 lines

oslib-posix.c void *qemu_oom_check(void *ptr) · line 84

Quoted 11 lines
oslib-posix.c +1 -1
index b6a3c7f..f978d56 100644
@@ -80,7 +80,7 @@ void *qemu_oom_check(void *ptr)
 {
     if (ptr == NULL) {
         fprintf(stderr, "Failed to allocate memory: %s\n", 
 strerror(errno));
-        abort();
+        exit(EXIT_FAILURE);

exit() will call any atexit()/on_exit() handlers, as well as trying to flush I/O streams. Any of these actions may require further memory allocations, which will likely fail, or worse cause this code to re-enter itself if an atexit() handler calls qemu_malloc

Quoted 5 lines

Nice, very reasonable.

Quoted 3 lines

The only option other than abort(), is to use _Exit() which doesn't try to run cleanup handlers.

I will try to send out v2

Could you please explain why calling exit, _Exit or _exit is more reasonable than calling abort?

abort can create core dumps or start a debugger which is useful for me and maybe other developers, too.

#4 lore raw
Quoted 39 lines · Stefan Weil

Am 10.02.2012 16:13, schrieb Zhi Yong Wu:

Quoted 37 lines
Quoted 20 lines · Daniel P. Berrange
Quoted 18 lines · Zhi Yong Wu

From: Zhi Yong Wu <[email protected]>

---
 oslib-posix.c |    4 ++--
 oslib-win32.c |    4 ++--

 2 files changed, 4 insertions(+), 4 deletions(-)
oslib-posix.c +0 -0
index b6a3c7f..f978d56 100644
@@ -80,7 +80,7 @@ void *qemu_oom_check(void *ptr)
  {
     if (ptr == NULL) {
         fprintf(stderr, "Failed to allocate memory: %s\n",
 strerror(errno));
Quoted 8 lines

oslib-posix.c void *qemu_oom_check(void *ptr) · line 84

Quoted 2 lines
oslib-posix.c +1 -1
-        abort();
+        exit(EXIT_FAILURE);

exit() will call any atexit()/on_exit() handlers, as well as trying to flush I/O streams. Any of these actions may require further memory allocations, which will likely fail, or worse cause this code to re-enter itself if an atexit() handler calls qemu_malloc

Nice, very reasonable.

Quoted 4 lines

The only option other than abort(), is to use  _Exit() which doesn't try to run cleanup handlers.

Quoted 8 lines
Quoted 1 line

I will try to send out v2

Could you please explain why calling exit, _Exit or _exit is more reasonable than calling abort?

abort can create core dumps or start a debugger which is useful for me and maybe other developers, too.

pls refer to http://lists.gnu.org/archive/html/qemu-devel/2012-02/msg01270.html.
In the scenario, the user should not see core dump, and he perhaps think that one bug exists in qemu code.
So we hope to use _Exit() instead of abort() here.

Quoted 1 line
Signature · 3 lines
Regards,

Zhi Yong Wu
#5 lore raw

Am 13.02.2012 03:37, schrieb Zhi Yong Wu:

Quoted 46 lines · Stefan Weil
Quoted 45 lines

Am 10.02.2012 16:13, schrieb Zhi Yong Wu:

Quoted 31 lines
Quoted 20 lines · Daniel P. Berrange
Quoted 18 lines · Zhi Yong Wu

From: Zhi Yong Wu <[email protected]>

---
 oslib-posix.c |    4 ++--
 oslib-win32.c |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
oslib-posix.c +0 -0
index b6a3c7f..f978d56 100644
@@ -80,7 +80,7 @@ void *qemu_oom_check(void *ptr)
 {
    if (ptr == NULL) {
        fprintf(stderr, "Failed to allocate memory: %s\n",
 strerror(errno));
Quoted 8 lines

oslib-posix.c void *qemu_oom_check(void *ptr) · line 84

Quoted 2 lines
oslib-posix.c +1 -1
-        abort();
+        exit(EXIT_FAILURE);

exit() will call any atexit()/on_exit() handlers, as well as trying to flush I/O streams. Any of these actions may require further memory allocations, which will likely fail, or worse cause this code to re-enter itself if an atexit() handler calls qemu_malloc

Quoted 7 lines

Nice, very reasonable.

Quoted 4 lines

The only option other than abort(), is to use _Exit() which doesn't try to run cleanup handlers.

I will try to send out v2

Could you please explain why calling exit, _Exit or _exit is more reasonable than calling abort?

Quoted 6 lines
Quoted 2 lines

abort can create core dumps or start a debugger which is useful for me and maybe other developers, too.

pls refer to http://lists.gnu.org/archive/html/qemu-devel/2012-02/msg01270.html.
In the scenario, the user should not see core dump, and he perhaps think that one bug exists in qemu code.
So we hope to use _Exit() instead of abort() here.

So you say that you don't want a core dump just because the user called QEMU with -m 4000 or some other large value.

Allocating RAM for the emulated machine is perhaps the only scenario where a core dump is indeed not reasonable. In most other cases, out-of-memory is an indication of a QEMU internal problem, so a core dump should be written.

I therefore suggest to restrict any modification to the handling of -m. In that case you could even improve the error message by telling the user how much memory would be possible. Simply call the allocating function with decreasing values until it no longer fails.

Regards,
Stefan Weil

#6 lore raw
Quoted 66 lines · Stefan Weil

Am 13.02.2012 03:37, schrieb Zhi Yong Wu:

Quoted 54 lines · Stefan Weil
Quoted 53 lines

Am 10.02.2012 16:13, schrieb Zhi Yong Wu:

Quoted 39 lines
Quoted 23 lines · Daniel P. Berrange
Quoted 20 lines · Zhi Yong Wu

From: Zhi Yong Wu <[email protected]>

---
 oslib-posix.c |    4 ++--
 oslib-win32.c |    4 ++--

 2 files changed, 4 insertions(+), 4 deletions(-)
oslib-posix.c +0 -1
index b6a3c7f..f978d56 100644
@@ -80,7 +80,7 @@ void *qemu_oom_check(void *ptr)
  {
    if (ptr == NULL) {
        fprintf(stderr, "Failed to allocate memory: %s\n",
 strerror(errno));
-        abort();
Quoted 8 lines

oslib-posix.c void *qemu_oom_check(void *ptr) · line 84

Quoted 1 line
oslib-posix.c +1 -0
+        exit(EXIT_FAILURE);

exit() will call any atexit()/on_exit() handlers, as well as trying to flush I/O streams. Any of these actions may require further memory allocations, which will likely fail, or worse cause this code to re-enter itself if an atexit() handler calls qemu_malloc

Nice, very reasonable.

Quoted 3 lines
Quoted 5 lines
Quoted 2 lines

The only option other than abort(), is to use  _Exit() which doesn't try to run cleanup handlers.

I will try to send out v2

Could you please explain why calling exit, _Exit or _exit is more reasonable than calling abort?

Quoted 8 lines
Quoted 2 lines

abort can create core dumps or start a debugger which is useful for me and maybe other developers, too.

pls refer to
http://lists.gnu.org/archive/html/qemu-devel/2012-02/msg01270.html.
In the scenario, the user should not see core dump, and he perhaps think that one bug exists in qemu code.
So we hope to use _Exit() instead of abort() here.

Quoted 7 lines

So you say that you don't want a core dump just because the user called QEMU with -m 4000 or some other large value.

Allocating RAM for the emulated machine is perhaps the only scenario where a core dump is indeed not reasonable. In most other cases, out-of-memory is an indication of a QEMU internal problem, so a core dump should be written.

Allocating guest memory could fail and we should give a reasonable error and exit with a failure. I think this might be the one case where we *do* want to handle memory allocation NULL return. In other words, perhaps we should call memory allocating functions directly here instead of using the typical QEMU abort-on-failure wrappers.

Stefan

#7 lore raw
Quoted 11 lines · Stefan Hajnoczi
Quoted 4 lines · Stefan Weil

Allocating RAM for the emulated machine is perhaps the only scenario where a core dump is indeed not reasonable. In most other cases, out-of-memory is an indication of a QEMU internal problem, so a core dump should be written.

Allocating guest memory could fail and we should give a reasonable error and exit with a failure. I think this might be the one case where we *do* want to handle memory allocation NULL return. In other words, perhaps we should call memory allocating functions directly here instead of using the typical QEMU abort-on-failure wrappers.

g_try_malloc

glib already has a suite of functions for this.

Regards,

Anthony Liguori

Quoted 3 lines

Stefan

#8 lore raw
In reply to Stefan Weil
Quoted 49 lines · Stefan Weil

Am 13.02.2012 03:37, schrieb Zhi Yong Wu:

Quoted 48 lines · Stefan Weil
Quoted 47 lines

Am 10.02.2012 16:13, schrieb Zhi Yong Wu:

Quoted 31 lines
Quoted 20 lines · Daniel P. Berrange
Quoted 18 lines · Zhi Yong Wu

From: Zhi Yong Wu <[email protected]>

---
oslib-posix.c | 4 ++--
oslib-win32.c | 4 ++--

2 files changed, 4 insertions(+), 4 deletions(-)
oslib-posix.c +0 -0
index b6a3c7f..f978d56 100644
@@ -80,7 +80,7 @@ void *qemu_oom_check(void *ptr)
 {
 if (ptr == NULL) {
 fprintf(stderr, "Failed to allocate memory: %s\n",
 strerror(errno));
Quoted 8 lines

oslib-posix.c void *qemu_oom_check(void *ptr) · line 84

Quoted 2 lines
oslib-posix.c +1 -1
- abort();
+ exit(EXIT_FAILURE);

exit() will call any atexit()/on_exit() handlers, as well as trying to flush I/O streams. Any of these actions may require further memory allocations, which will likely fail, or worse cause this code to re-enter itself if an atexit() handler calls qemu_malloc

Quoted 7 lines

Nice, very reasonable.

Quoted 4 lines

The only option other than abort(), is to use _Exit() which doesn't try to run cleanup handlers.

I will try to send out v2

Could you please explain why calling exit, _Exit or _exit is more reasonable than calling abort?

abort can create core dumps or start a debugger which is useful for me and maybe other developers, too.

Quoted 7 lines
Quoted 4 lines

pls refer to http://lists.gnu.org/archive/html/qemu-devel/2012-02/msg01270.html.
In the scenario, the user should not see core dump, and he perhaps think that one bug exists in qemu code.
So we hope to use _Exit() instead of abort() here.

So you say that you don't want a core dump just because the user called QEMU with -m 4000 or some other large value.

Then use g_try_malloc() when allocating ram and give a nice error message.

Normal malloc failures should call abort().

Regards,

Anthony Liguori

Quoted 16 lines

Allocating RAM for the emulated machine is perhaps the only scenario where a core dump is indeed not reasonable. In most other cases, out-of-memory is an indication of a QEMU internal problem, so a core dump should be written.

I therefore suggest to restrict any modification to the handling of -m. In that case you could even improve the error message by telling the user how much memory would be possible. Simply call the allocating function with decreasing values until it no longer fails.

Regards,
Stefan Weil

#9 lore raw
In reply to Stefan Weil
Quoted 32 lines · Stefan Weil

Am 10.02.2012 16:13, schrieb Zhi Yong Wu:

Quoted 31 lines
Quoted 9 lines · Daniel P. Berrange
Quoted 8 lines · Zhi Yong Wu

From: Zhi Yong Wu <[email protected]>

---
 oslib-posix.c |    4 ++--
 oslib-win32.c |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
Quoted 16 lines

oslib-posix.c void *qemu_oom_check(void *ptr) · line 84

Quoted 11 lines
oslib-posix.c +1 -1
index b6a3c7f..f978d56 100644
@@ -80,7 +80,7 @@ void *qemu_oom_check(void *ptr)
 {
     if (ptr == NULL) {
         fprintf(stderr, "Failed to allocate memory: %s\n",
 strerror(errno));
-        abort();
+        exit(EXIT_FAILURE);

exit() will call any atexit()/on_exit() handlers, as well as trying to flush I/O streams. Any of these actions may require further memory allocations, which will likely fail, or worse cause this code to re-enter itself if an atexit() handler calls qemu_malloc

Nice, very reasonable.

Quoted 3 lines

The only option other than abort(), is to use _Exit() which doesn't try to run cleanup handlers.

Quoted 7 lines
Quoted 1 line

I will try to send out v2

Could you please explain why calling exit, _Exit or _exit is more reasonable than calling abort?

abort can create core dumps or start a debugger which is useful for me and maybe other developers, too.

I consider abort() on OOM somewhat eccentric. abort() is for programming errors. Resource shortage is an environmental error that is sometimes (but not always) caused by a programming error.

I'd rather inconvenience programmers (by making it a little bit harder to debug programming errors that cause OOM) than confuse users with inappropriate scary "crashes".

#10 lore raw
Quoted 7 lines · Markus Armbruster

I consider abort() on OOM somewhat eccentric.  abort() is for programming errors.  Resource shortage is an environmental error that is sometimes (but not always) caused by a programming error.

I'd rather inconvenience programmers (by making it a little bit harder to debug programming errors that cause OOM) than confuse users with inappropriate scary "crashes".

I think the rationale for aborting here is that you're already accepting "program just dies" behaviour for out-of-memory errors via the kernel's OOM-killer...

-- PMM

#11 lore raw
In reply to Markus Armbruster
Quoted 10 lines
Quoted 2 lines

abort can create core dumps or start a debugger which is useful for me and maybe other developers, too.

I consider abort() on OOM somewhat eccentric. abort() is for programming errors. Resource shortage is an environmental error that is sometimes (but not always) caused by a programming error.

I'd rather inconvenience programmers (by making it a little bit harder to debug programming errors that cause OOM) than confuse users with inappropriate scary "crashes".

While I agree that abort() is not the most friendly failure method, I don't tthink it's worth trying to handle OOM gracefully. Once we hit OOM I'd say we're pretty much beyond hope. The best thing we can do is exist as quickly as possible. For the vast majority of systems there isn't any reason to believe things will somehow get better if we try again later.

Initial guest RAM allocation is maybe a special case worth a polite error. OTOH if you're near the limit then there's a fair chance the -m allocation will succeed, but some later allocation will not.

The only way to handle this rebustly is to pre-allocate all the memory we're ever going to need[1]. I don't see that happening.

Paul

[1] And make sure the kernel isn't lying about how much ram we can have.

#12 lore raw
Quoted 17 lines · Paul Brook
Quoted 10 lines
Quoted 2 lines

abort can create core dumps or start a debugger which is useful for me and maybe other developers, too.

I consider abort() on OOM somewhat eccentric. abort() is for programming errors. Resource shortage is an environmental error that is sometimes (but not always) caused by a programming error.

I'd rather inconvenience programmers (by making it a little bit harder to debug programming errors that cause OOM) than confuse users with inappropriate scary "crashes".

While I agree that abort() is not the most friendly failure method, I don't tthink it's worth trying to handle OOM gracefully. Once we hit OOM I'd say we're pretty much beyond hope. The best thing we can do is exist as quickly as possible. For the vast majority of systems there isn't any reason to believe things will somehow get better if we try again later.

Quoted 6 lines

Initial guest RAM allocation is maybe a special case worth a polite error. OTOH if you're near the limit then there's a fair chance the -m allocation will succeed, but some later allocation will not.

The only way to handle this rebustly is to pre-allocate all the memory we're ever going to need[1]. I don't see that happening.

FWIW, users can already opt-in to pre-allocation if running KVM enabled QEMU

-mem-path /dev/shm -mem-prealloc (or /dev/hugepages more usefully)

Regards,
Daniel

Signature · 4 lines
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|
#13 lore raw
Quoted 7 lines
Quoted 2 lines

The only way to handle this rebustly is to pre-allocate all the memory we're ever going to need[1]. I don't see that happening.

FWIW, users can already opt-in to pre-allocation if running KVM enabled QEMU

-mem-path /dev/shm -mem-prealloc (or /dev/hugepages more usefully)

No, that's something different. -mem-prealloc causes MAP_POPULATE to be passed when allocating guest ram, working around the fact that most modern implementations of mmap lie. It has no effect on how all the other memory qemu uses is allocated.

Paul

#14 lore raw
In reply to Markus Armbruster
Quoted 42 lines · Markus Armbruster
Quoted 32 lines · Stefan Weil

Am 10.02.2012 16:13, schrieb Zhi Yong Wu:

Quoted 31 lines
Quoted 9 lines · Daniel P. Berrange
Quoted 8 lines · Zhi Yong Wu

From: Zhi Yong Wu<[email protected]>

---
  oslib-posix.c |    4 ++--
  oslib-win32.c |    4 ++--
  2 files changed, 4 insertions(+), 4 deletions(-)
Quoted 16 lines

oslib-posix.c void *qemu_oom_check(void *ptr) · line 84

Quoted 11 lines
oslib-posix.c +1 -1
index b6a3c7f..f978d56 100644
@@ -80,7 +80,7 @@ void *qemu_oom_check(void *ptr)
  {
      if (ptr == NULL) {
          fprintf(stderr, "Failed to allocate memory: %s\n",
 strerror(errno));
-        abort();
+        exit(EXIT_FAILURE);

exit() will call any atexit()/on_exit() handlers, as well as trying to flush I/O streams. Any of these actions may require further memory allocations, which will likely fail, or worse cause this code to re-enter itself if an atexit() handler calls qemu_malloc

Nice, very reasonable.

Quoted 3 lines

The only option other than abort(), is to use _Exit() which doesn't try to run cleanup handlers.

Quoted 7 lines
Quoted 1 line

I will try to send out v2

Could you please explain why calling exit, _Exit or _exit is more reasonable than calling abort?

abort can create core dumps or start a debugger which is useful for me and maybe other developers, too.

Quoted 7 lines

I consider abort() on OOM somewhat eccentric. abort() is for programming errors. Resource shortage is an environmental error that is sometimes (but not always) caused by a programming error.

I'd rather inconvenience programmers (by making it a little bit harder to debug programming errors that cause OOM) than confuse users with inappropriate scary "crashes".

OOM is a going to 99% of the time be a bug in QEMU.

For the rare exceptions (like a bad -m argument), we should handle those as special cases.

Regards,

Anthony Liguori

Quoted 1 line
#15 lore raw
In reply to Daniel P. Berrange
Quoted 12 lines · Daniel P. Berrange

oslib-posix.c void *qemu_oom_check(void *ptr) · line 83

Quoted 6 lines
oslib-posix.c +1 -1
@@ -80,7 +80,7 @@ void *qemu_oom_check(void *ptr)
 {
     if (ptr == NULL) {
         fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno));
-        abort();
+        exit(EXIT_FAILURE);

exit() will call any atexit()/on_exit() handlers, as well as trying to flush I/O streams. Any of these actions may require further memory allocations, which will likely fail, or worse cause this code to re-enter itself if an atexit() handler calls qemu_malloc

Quoted 2 lines

The only option other than abort(), is to use _Exit() which doesn't try to run cleanup handlers.

Correct, but in that case, then you need to fflush(stderr) prior to _Exit(), or else use write() rather than fprintf(), since otherwise your attempt at a nice oom error message is lost.

Signature · 2 lines
Eric Blake   [email protected]    +1-919-301-3266
Libvirt virtualization library http://libvirt.org
#16 lore raw
Quoted 14 lines · Eric Blake
Quoted 12 lines · Daniel P. Berrange

oslib-posix.c void *qemu_oom_check(void *ptr) · line 83

Quoted 6 lines
oslib-posix.c +1 -1
@@ -80,7 +80,7 @@ void *qemu_oom_check(void *ptr)
  {
      if (ptr == NULL) {
          fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno));
-        abort();
+        exit(EXIT_FAILURE);

exit() will call any atexit()/on_exit() handlers, as well as trying to flush I/O streams. Any of these actions may require further memory allocations, which will likely fail, or worse cause this code to re-enter itself if an atexit() handler calls qemu_malloc

Quoted 6 lines
Quoted 2 lines

The only option other than abort(), is to use  _Exit() which doesn't try to run cleanup handlers.

Correct, but in that case, then you need to fflush(stderr) prior to _Exit(), or else use write() rather than fprintf(), since otherwise your attempt at a nice oom error message is lost.

Great, pls see next version.

Quoted 5 lines

--
Eric Blake   [email protected]    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

Signature · 3 lines
Regards,

Zhi Yong Wu
#17 lore raw
In reply to Eric Blake
Quoted 14 lines · Eric Blake
Quoted 12 lines · Daniel P. Berrange

oslib-posix.c void *qemu_oom_check(void *ptr) · line 83

Quoted 6 lines
oslib-posix.c +1 -1
@@ -80,7 +80,7 @@ void *qemu_oom_check(void *ptr)
 {
     if (ptr == NULL) {
         fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno));
-        abort();
+        exit(EXIT_FAILURE);

exit() will call any atexit()/on_exit() handlers, as well as trying to flush I/O streams. Any of these actions may require further memory allocations, which will likely fail, or worse cause this code to re-enter itself if an atexit() handler calls qemu_malloc

Quoted 6 lines
Quoted 2 lines

The only option other than abort(), is to use _Exit() which doesn't try to run cleanup handlers.

Correct, but in that case, then you need to fflush(stderr) prior to _Exit(), or else use write() rather than fprintf(), since otherwise your attempt at a nice oom error message is lost.

IIRC, stderr is not buffered, so should not need to be flushed.

Daniel

Signature · 4 lines
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|