Oren Eini

aka Ayende Rahien

Oren Eini

CEO of RavenDB

a NoSQL Open Source Document Database

Get in touch with me:

oren@ravendb.net +972 52-548-6969

Posts: 7,575
|
Comments: 51,188

Copyright ©️ Ayende Rahien 2004 — 2025

Privacy Policy · Terms
filter by tags archive
stack view grid view
  • architecture (606) rss
  • bugs (450) rss
  • challanges (123) rss
  • community (377) rss
  • databases (481) rss
  • design (893) rss
  • development (640) rss
  • hibernating-practices (71) rss
  • miscellaneous (592) rss
  • performance (397) rss
  • programming (1085) rss
  • raven (1442) rss
  • ravendb.net (526) rss
  • reviews (184) rss
  • 2025
    • May (7)
    • April (10)
    • March (10)
    • February (7)
    • January (12)
  • 2024
    • December (3)
    • November (2)
    • October (1)
    • September (3)
    • August (5)
    • July (10)
    • June (4)
    • May (6)
    • April (2)
    • March (8)
    • February (2)
    • January (14)
  • 2023
    • December (4)
    • October (4)
    • September (6)
    • August (12)
    • July (5)
    • June (15)
    • May (3)
    • April (11)
    • March (5)
    • February (5)
    • January (8)
  • 2022
    • December (5)
    • November (7)
    • October (7)
    • September (9)
    • August (10)
    • July (15)
    • June (12)
    • May (9)
    • April (14)
    • March (15)
    • February (13)
    • January (16)
  • 2021
    • December (23)
    • November (20)
    • October (16)
    • September (6)
    • August (16)
    • July (11)
    • June (16)
    • May (4)
    • April (10)
    • March (11)
    • February (15)
    • January (14)
  • 2020
    • December (10)
    • November (13)
    • October (15)
    • September (6)
    • August (9)
    • July (9)
    • June (17)
    • May (15)
    • April (14)
    • March (21)
    • February (16)
    • January (13)
  • 2019
    • December (17)
    • November (14)
    • October (16)
    • September (10)
    • August (8)
    • July (16)
    • June (11)
    • May (13)
    • April (18)
    • March (12)
    • February (19)
    • January (23)
  • 2018
    • December (15)
    • November (14)
    • October (19)
    • September (18)
    • August (23)
    • July (20)
    • June (20)
    • May (23)
    • April (15)
    • March (23)
    • February (19)
    • January (23)
  • 2017
    • December (21)
    • November (24)
    • October (22)
    • September (21)
    • August (23)
    • July (21)
    • June (24)
    • May (21)
    • April (21)
    • March (23)
    • February (20)
    • January (23)
  • 2016
    • December (17)
    • November (18)
    • October (22)
    • September (18)
    • August (23)
    • July (22)
    • June (17)
    • May (24)
    • April (16)
    • March (16)
    • February (21)
    • January (21)
  • 2015
    • December (5)
    • November (10)
    • October (9)
    • September (17)
    • August (20)
    • July (17)
    • June (4)
    • May (12)
    • April (9)
    • March (8)
    • February (25)
    • January (17)
  • 2014
    • December (22)
    • November (19)
    • October (21)
    • September (37)
    • August (24)
    • July (23)
    • June (13)
    • May (19)
    • April (24)
    • March (23)
    • February (21)
    • January (24)
  • 2013
    • December (23)
    • November (29)
    • October (27)
    • September (26)
    • August (24)
    • July (24)
    • June (23)
    • May (25)
    • April (26)
    • March (24)
    • February (24)
    • January (21)
  • 2012
    • December (19)
    • November (22)
    • October (27)
    • September (24)
    • August (30)
    • July (23)
    • June (25)
    • May (23)
    • April (25)
    • March (25)
    • February (28)
    • January (24)
  • 2011
    • December (17)
    • November (14)
    • October (24)
    • September (28)
    • August (27)
    • July (30)
    • June (19)
    • May (16)
    • April (30)
    • March (23)
    • February (11)
    • January (26)
  • 2010
    • December (29)
    • November (28)
    • October (35)
    • September (33)
    • August (44)
    • July (17)
    • June (20)
    • May (53)
    • April (29)
    • March (35)
    • February (33)
    • January (36)
  • 2009
    • December (37)
    • November (35)
    • October (53)
    • September (60)
    • August (66)
    • July (29)
    • June (24)
    • May (52)
    • April (63)
    • March (35)
    • February (53)
    • January (50)
  • 2008
    • December (58)
    • November (65)
    • October (46)
    • September (48)
    • August (96)
    • July (87)
    • June (45)
    • May (51)
    • April (52)
    • March (70)
    • February (43)
    • January (49)
  • 2007
    • December (100)
    • November (52)
    • October (109)
    • September (68)
    • August (80)
    • July (56)
    • June (150)
    • May (115)
    • April (73)
    • March (124)
    • February (102)
    • January (68)
  • 2006
    • December (95)
    • November (53)
    • October (120)
    • September (57)
    • August (88)
    • July (54)
    • June (103)
    • May (89)
    • April (84)
    • March (143)
    • February (78)
    • January (64)
  • 2005
    • December (70)
    • November (97)
    • October (91)
    • September (61)
    • August (74)
    • July (92)
    • June (100)
    • May (53)
    • April (42)
    • March (41)
    • February (84)
    • January (31)
  • 2004
    • December (49)
    • November (26)
    • October (26)
    • September (6)
    • April (10)
RavenDB Workshops - Deep dive into practical use of Document Data Modeling
  previous post next post  
May 01 2010

Find the bug

time to read 1 min | 35 words

This code has a serious problem in it, can you figure out what it is?

image

Tweet Share Share 22 comments
Tags:
  • Bugs

  previous post next post  

Comments

Oded
01 May 2010
21:08 PM
Oded

There is not enough memory for creating a new OutOfMemoryException

gerbil
01 May 2010
21:14 PM
gerbil

Missing semicolon?

Kris-I
01 May 2010
21:25 PM
Kris-I

I think, you swallow the exception

Do this :

throw outOfMemoryError(ex.message, ex.InnerException)

junior programmer
01 May 2010
21:26 PM
junior programmer

you should just do throw rather than a new exception. if you throw new exception the "real" exception will be hidden inside inner exception and you need to loop through inner exception to find the "real" exception.

13xforever
01 May 2010
21:34 PM
13xforever

This is a classic example of why you shouldn't do

catch (Exception e)

{

...

}

Only this is more obvious.

Patrik
01 May 2010
21:34 PM
Patrik

Don't think you can catch OutOfMemoryException.

tobi
01 May 2010
21:42 PM
tobi

Depending on the hosting environment critical exception can cause a rude AppDomain unload. Your handler might not be executing et all.

Jason Meckley
01 May 2010
21:44 PM
Jason Meckley

I'm with Oded on this. how can you create a new exception to bubble up if you are out of memory.

wcoenen
01 May 2010
21:49 PM
wcoenen

This makes one wonder how the original OutOfMemoryException can be created and thrown in the first place.

Cory Foy
01 May 2010
22:26 PM
Cory Foy

OOM, like ExecutionEngineException and one other, are always on the heap because you can't guarantee during an OOM that you'll be able to create an object on the heap. You can see that by attaching with WinDBG and doing a "!dumpheap -type Exception".

For those wondering, you can absolutely catch OutOfMemoryExceptions. As noted here: stackoverflow.com/.../when-is-it-ok-to-catch-an... you may have an image editing application which is allocating a buffer. You need to be able to handle that condition. It's not fatal, unless it bubbles up. Or unless you were trying to autobox a variable and couldn't get even 12 bytes of memory.

I'm assuming that the screenshot cut off where you wrap the original OOM exception. Generally you don't throw a new exception, since you lose the stack trace, but I can't see the constructor to tell what you are doing there - so I'll assume you're doing the right thing. ;)

Something else to note - if your OOM exception path calls methods that may not have been JIT'd, then you can get even more fun because there isn't enough memory to store the compiled code in the metadata, nor update the pointers to it. This can result it even more OOM exceptions, and the framework can do all kinds of interesting things to make sure at least one OOM gets bubbled up.

Joseph Gutierrez
02 May 2010
01:20 AM
Joseph Gutierrez

Don't you want to release the resources that were being used that cause the OOM exception before throwing another exception?

manningj
02 May 2010
01:21 AM
manningj

not that it much matters, but as a point to some previous comments, as Cory mentions, someone could attempt to allocate something huge (say, 3GB on a 32-bit machine with the default 2/2 split) and that hits the OOM, but there may still be plenty of free memory that's sufficient for creating things like, say, an OOM exception.

Also, keep in mind that a lot of things in the 'try' block (not to mention potentially other things) may have just gone out of scope (lost their root reference path) so they may be free to get GC'd as part of the new OOM allocation if necessary.

Based on the comment it seems like you want to wrap the original OOM to get a new message. I've never tried it, but I wonder if you could just modify e.Message and then throw; to preserve the original stack without creating the outer wrapper.

Of course, since you mention the hint is for 32-bit users, it'd be potentially nice to wrap the 'hint' in an if IntPtr.Size == 4 and have the else case just throw; since there's no point in providing that hint to your 64-bit users :)

I have to admit I'm a little surprised that there hasn't been at least one comment of someone proposing trying to 'help' the memory situation manually (like WaitForPendingFinalizers and potentially doing a manual GC.Collect) before trying an allocation (even if just an OOM wrapper exception).

Gareth G
02 May 2010
02:10 AM
Gareth G

a) Swallows original exception, so no context propagated

b) Will there even be any memory to create the OOME ?

Cory Foy
02 May 2010
03:52 AM
Cory Foy

@Joseph: This is .NET, so there is no "release" concept. Not that would help you much here. You could theoretically set an object instance to null, and then manually call GC.Collect, but unless you were explicitly trying to allocate a specific block of memory and are trying to recover from a specific and well-tested block of code, anything "helpful" is likely just going to delay the problem and make debugging it even worse. The GC and memory manager have been written by some quite bright people, and while there are rare cases where you may know more than the Memory Manager, they are few and far between.

@manningj - That no one suggested that is either a sign of people knowing enough not to try that in a general case, or people not understanding enough about the framework to know what WaitForPendingFinalizers does, or even what really goes on during a GC. I'm hoping it's the former. ;)

Joseph Gutierrez
02 May 2010
05:08 AM
Joseph Gutierrez

@Cory, Normally I would have to agree, but If the resources are long lasting connections to sockets or the resources are into un-managed code you would, I believe, want to release them. Maybe even clean up some dangling delegates. Specifically, concerning bright people, there are constraints, limits, and contexts in which software will not perform as expected otherwise we wouldn't have exceptions ;)

I think the throwing of the of the second OOM after catching the first was for 32bit VM. A good disussion for this is here:

msdn.microsoft.com/en-us/magazine/cc163528.aspx#S8

Specifically, Determining What Caused an OOM Exception.

Howard Pinsley
02 May 2010
15:10 PM
Howard Pinsley

I'm confused. Why are you attempting to allocate an exception of the same type as what was caught? What additional information is being added? Even if you can allocate a new OutOfMemoryException object, what is gained over simply not catching the exception at all? I'm guessing the comment explains why, but I'm not following the reason?

Lee Dumond
02 May 2010
16:31 PM
Lee Dumond

For one thing, this code doesn't actually handle the exception. If you don't intend to handle the exception meaningfully, there is no reason to catch it in the first place.

Second, by throwing a new exception, you lose the original stack trace. From this point forward, an examination of the stack trace will make it appear as though this is where the error originated. At the very least, the new exception should include the original one in its InnerException property. Of course, you should take the opportunity to add more information at this point; otherwise, as mentioned, there's no point in having the catch at all.

fschwiet
02 May 2010
22:56 PM
fschwiet

@wcoenen

I'm pretty sure the original OOM exception is pre-allocated by the CLR. I remember talking to someone on the CLR test team when they found this bug.

Someone
04 May 2010
11:52 AM
Someone

new System.OutOfMemoryException();

notice the ();

Bunter
04 May 2010
17:11 PM
Bunter

So Ayende, you throw a topic in the air and just leave it here? You teaser.

Ayende Rahien
04 May 2010
17:51 PM
Ayende Rahien

Bunter,

Oded gave the right answer right away...

jmorris
04 May 2010
22:38 PM
jmorris

Wow, that one was to easy...took me seconds. Your losing your touch ;)

Comment preview

Comments have been closed on this topic.

Markdown formatting

ESC to close

Markdown turns plain text formatting into fancy HTML formatting.

Phrase Emphasis

*italic*   **bold**
_italic_   __bold__

Links

Inline:

An [example](http://url.com/ "Title")

Reference-style labels (titles are optional):

An [example][id]. Then, anywhere
else in the doc, define the link:
  [id]: http://example.com/  "Title"

Images

Inline (titles are optional):

![alt text](/path/img.jpg "Title")

Reference-style:

![alt text][id]
[id]: /url/to/img.jpg "Title"

Headers

Setext-style:

Header 1
========
Header 2
--------

atx-style (closing #'s are optional):

# Header 1 #
## Header 2 ##
###### Header 6

Lists

Ordered, without paragraphs:

1.  Foo
2.  Bar

Unordered, with paragraphs:

*   A list item.
    With multiple paragraphs.
*   Bar

You can nest them:

*   Abacus
    * answer
*   Bubbles
    1.  bunk
    2.  bupkis
        * BELITTLER
    3. burper
*   Cunning

Blockquotes

> Email-style angle brackets
> are used for blockquotes.
> > And, they can be nested.
> #### Headers in blockquotes
> 
> * You can quote a list.
> * Etc.

Horizontal Rules

Three or more dashes or asterisks:

---
* * *
- - - - 

Manual Line Breaks

End a line with two or more spaces:

Roses are red,   
Violets are blue.

Fenced Code Blocks

Code blocks delimited by 3 or more backticks or tildas:

```
This is a preformatted
code block
```

Header IDs

Set the id of headings with {#<id>} at end of heading line:

## My Heading {#myheading}

Tables

Fruit    |Color
---------|----------
Apples   |Red
Pears	 |Green
Bananas  |Yellow

Definition Lists

Term 1
: Definition 1
Term 2
: Definition 2

Footnotes

Body text with a footnote [^1]
[^1]: Footnote text here

Abbreviations

MDD <- will have title
*[MDD]: MarkdownDeep

 

FUTURE POSTS

  1. Optimizing the cost of clearing a set - 3 days from now
  2. Scaling HNSW in RavenDB: Optimizing for inadequate hardware - 5 days from now

There are posts all the way to May 14, 2025

RECENT SERIES

  1. RavenDB News (2):
    02 May 2025 - May 2025
  2. Recording (15):
    30 Apr 2025 - Practical AI Integration with RavenDB
  3. Production Postmortem (52):
    07 Apr 2025 - The race condition in the interlock
  4. RavenDB (13):
    02 Apr 2025 - .NET Aspire integration
  5. RavenDB 7.1 (6):
    18 Mar 2025 - One IO Ring to rule them all
View all series

RECENT COMMENTS

  • But in case you have nullability checks enabled (i.e. `<Nullable>enable</Nullable>`), then you'll have a compiler warning on ...
    By Samyon Ristov on The null check that didn't check for nulls
  • Grok wasn't *wrong*. It only said that `_items` can't be null for the condition to evaluate to `true`, but didn't say anythi...
    By Johannes Egger on The null check that didn't check for nulls
  • When I started enabling NRT, I remember I was initially confused when all variables (for reference types) declared with `var`...
    By riccardo on The null check that didn't check for nulls
  • That is surprising - I think of var as a shorthand that does not affect the final result of the compilation. I wouldn't expec...
    By Chris B on The null check that didn't check for nulls
  • "It is also about as friendly as a monkey with a sore tooth and an alcohol addiction." And I have to clean my monitor.
    By Tim on When racing the Heisenbug, code quality goes out the Windows

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats
}