saifi009 / bitcoinj

Automatically exported from code.google.com/p/bitcoinj
0 stars 0 forks source link

StackOverflowError when sending my last Bitcoins #36

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Have a look at

http://blockexplorer.com/testnet/address/mukdwUGeAjJiyDsg4pGU9S3xaQbJfa6JFe

After I was entering the last transaction 
(05acd31488ab73fb901ac8882989042ae288b2ccae8e6b6e96838ba517b9123b) which was 
using all my remaining 5 Bitcoins, the client immediately crashed (I guess 
while saving the wallet).

Note that I have applied the patch from issue 35.

E/AndroidRuntime(24167): java.lang.StackOverflowError
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.dumpCycle(ObjectOutputStream.java:471)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1739)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1205)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
E/AndroidRuntime(24167):    at java.util.ArrayList.writeObject(ArrayList.java:651)
E/AndroidRuntime(24167):    at java.lang.reflect.Method.invokeNative(Native 
Method)
E/AndroidRuntime(24167):    at java.lang.reflect.Method.invoke(Method.java:507)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1219)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
E/AndroidRuntime(24167):    at java.util.ArrayList.writeObject(ArrayList.java:651)
E/AndroidRuntime(24167):    at java.lang.reflect.Method.invokeNative(Native 
Method)
E/AndroidRuntime(24167):    at java.lang.reflect.Method.invoke(Method.java:507)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1219)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
E/AndroidRuntime(24167):    at 
java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)

Original issue reported on code.google.com by andreas....@gmail.com on 2 Jul 2011 at 7:38

GoogleCodeExporter commented 9 years ago
That's interesting. Is it the full stack trace? Seems the bottom may have been 
truncated.

Presumably this is a bug in the Java serialization implementation (on Android 
only?). I don't think it's supposed to be possible to crash the serializer like 
that.

If some platforms have a buggy serialization engine, that's a strike against 
using it for wallets.

Original comment by hearn@google.com on 2 Jul 2011 at 8:52

GoogleCodeExporter commented 9 years ago
Yes, it is truncated at the bottom. The above output is followed by these lines:

E/AndroidRuntime(24167):        at java.io
W/ActivityManager(  103):   Force finishing activity 
de.schildbach.wallet/.WalletActivity

I would very much like to send you the wallet, but unfortunately I still 
haven't had the fix in place that put the wallet in a world readable location 
for testnet. (I have fixed this now. I promise ;-)

Original comment by andreas....@gmail.com on 2 Jul 2011 at 9:08

GoogleCodeExporter commented 9 years ago
This issue was closed by revision r124.

Original comment by hearn@google.com on 6 Jul 2011 at 12:12

GoogleCodeExporter commented 9 years ago
Oops, typo closed wrong bug.

Original comment by hearn@google.com on 6 Jul 2011 at 12:14

GoogleCodeExporter commented 9 years ago
Ah, got it again. Attaching the wallet this time.

Original comment by andreas....@gmail.com on 7 Jul 2011 at 11:51

Attachments:

GoogleCodeExporter commented 9 years ago
And here is a bit more of stack trace this time:

W/InputManagerService(  103): Starting input on non-focused client 
com.android.internal.view.IInputMethodClient$Stub$Proxy@406515a0 (uid=10050 
pid=4407)
D/dalvikvm(  174): GC_EXTERNAL_ALLOC freed 75K, 43% free 3640K/6343K, external 
4957K/4964K, paused 52ms
D/dalvikvm(  174): GC_EXTERNAL_ALLOC freed 91K, 44% free 3610K/6343K, external 
5219K/5502K, paused 50ms
I/System.out( 4407): about to send 22000000 (BTC 0.22) to 
mjcZDSDtroERr1jnnZdwjWhTjjVbhGW86H
W/System.err( 4407): 262418 [main] INFO com.google.bitcoin.core.Wallet - 
Creating send tx to mjcZDSDtroERr1jnnZdwjWhTjjVbhGW86H for 0.22
W/System.err( 4407): 262420 [main] INFO com.google.bitcoin.core.Wallet -   with 
0.78 coins change
D/dalvikvm( 4407): GC_CONCURRENT freed 1104K, 50% free 3678K/7239K, external 
2785K/3201K, paused 2ms+8ms
W/System.err( 4407): 262791 [main] INFO com.google.bitcoin.core.Wallet -   
created c43b589872623fb7c0edbfc026b7e7c9282b65de9cc488f2a62f5982b718fce2
I/System.out( 4407): discovering peers
W/System.err( 4407): 263350 [backgroundThread] WARN 
com.google.bitcoin.discovery.IrcDiscovery - IRC nick does not parse as base58: 
u2f43AKh726St3P
I/System.out( 4407): 59 peers discovered, took 639 ms
I/System.out( 4407): broadcasting to com.google.bitcoin.core.Peer@40616c58
W/System.err( 4407): 263439 [main] INFO com.google.bitcoin.core.Wallet - 
confirmSend of c43b589872623fb7c0edbfc026b7e7c9282b65de9cc488f2a62f5982b718fce2
I/System.out( 4407): broadcasting to com.google.bitcoin.core.Peer@4057b0f8
I/System.out( 4407): broadcasting to com.google.bitcoin.core.Peer@406302e0
I/System.out( 4407): broadcasting to com.google.bitcoin.core.Peer@40610540
I/dalvikvm( 4407): threadid=1: stack overflow on call to 
Ljava/util/IdentityHashMap;.findIndex:ILL
I/dalvikvm( 4407):   method requires 32+20+12=64 bytes, fp is 0x4214a310 (16 
left)
I/dalvikvm( 4407):   expanding stack end (0x4214a300 to 0x4214a000)
I/dalvikvm( 4407): Shrank stack (to 0x4214a300, curFrame is 0x4214a4ac)
D/AndroidRuntime( 4407): Shutting down VM
W/dalvikvm( 4407): threadid=1: thread exiting with uncaught exception 
(group=0x40015560)
I/System.out( 4407): broadcasting to com.google.bitcoin.core.Peer@4061be78
I/System.out( 4407): broadcasting to com.google.bitcoin.core.Peer@40616c58
E/AndroidRuntime( 4407): FATAL EXCEPTION: main
E/AndroidRuntime( 4407): java.lang.StackOverflowError
E/AndroidRuntime( 4407):    at 
java.util.IdentityHashMap.get(IdentityHashMap.java:371)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.dumpCycle(ObjectOutputStream.java:471)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1739)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1205)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
E/AndroidRuntime( 4407):    at java.util.ArrayList.writeObject(ArrayList.java:651)
E/AndroidRuntime( 4407):    at java.lang.reflect.Method.invokeNative(Native 
Method)
E/AndroidRuntime( 4407):    at java.lang.reflect.Method.invoke(Method.java:507)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1219)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1205)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1143)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:413)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1241)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
E/AndroidRuntime( 4407):    at java.util.HashSet.writeObject(HashSet.java:192)
E/AndroidRuntime( 4407):    at java.lang.reflect.Method.invokeNative(Native 
Method)
E/AndroidRuntime( 4407):    at java.lang.reflect.Method.invoke(Method.java:507)
E/AndroidRuntime( 4407):    at 
java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1219)
E/AndroidRuntime( 4407):    at java.io.ObjectOutputStream.write
I/System.out( 4407): broadcasting to com.google.bitcoin.core.Peer@4057b0f8
I/System.out( 4407): broadcasting to com.google.bitcoin.core.Peer@406302e0
D/dalvikvm( 4407): GC_CONCURRENT freed 1178K, 51% free 3672K/7367K, external 
2817K/3201K, paused 2ms+6ms
W/ActivityManager(  103):   Force finishing activity 
de.schildbach.wallet/.SendCoinsActivity

Original comment by andreas....@gmail.com on 7 Jul 2011 at 11:52

GoogleCodeExporter commented 9 years ago
Another one of these StackOverflowErrors:

http://i.imgur.com/vA7lc.jpg

Original comment by andreas....@gmail.com on 15 Jul 2011 at 12:17

GoogleCodeExporter commented 9 years ago
This issue has got nothing to do with "sending the last coins".

Looks like this is a quite old problem with Java serialization:

http://bugs.sun.com/view_bug.do?bug_id=4152790

http://stackoverflow.com/questions/438875/stackoverflowerror-when-serializing-an
-object-in-java

Let me quote the stack overflow page:

    Java serialization keeps a record of every object written to a stream. If the same object is encountered a second time, only a reference to it is written to the stream, and not a second copy of the object; so circular references aren't the problem here.

    But serialization is vulnerable to stack overflow for certain kinds of structures; for example, a long linked list with no special writeObject() methods will be serialized by recursively writing each link. If you've got a 100,000 links, you're going to try to use 100,000 stack frames, and quite likely fail with a StackOverflowError.

    It's possible to define a writeObject() method for such a list class that, when the first link is serialized, simply walks the list and serializes each link iteratively; this will prevent the default recursive mechanism from being used.

Original comment by andreas....@gmail.com on 16 Jul 2011 at 5:17

GoogleCodeExporter commented 9 years ago
Have you got a more recent example wallet? It seems the one that's attached no 
longer deserializes.

Original comment by hearn@google.com on 18 Jul 2011 at 9:07

GoogleCodeExporter commented 9 years ago
If you can reproduce the issue, you could try just winding up the stack size 
for now. It's obviously only a temporary fix but might let you deserialize 
wallets that got too complicated for the stack size allowed. See the Thread 
constructor that lets you control the size.

I played about with stuffing wallets full of transactions on the desktop JRE 
but couldn't reproduce the problem.

Original comment by hearn@google.com on 18 Jul 2011 at 10:14

GoogleCodeExporter commented 9 years ago
I've upped stack to 64 kb (from 8 kb? - don't know) and this seeems to do the 
trick with my problem-ridden testnet wallet.

Original comment by andreas....@gmail.com on 18 Jul 2011 at 11:24

GoogleCodeExporter commented 9 years ago
I just hit the stack size boundary again with my test wallet with these two 
addresses:

http://blockexplorer.com/testnet/address/mwhsLCBMmTXgzjMXhteKk63siFRsCboVEm
http://blockexplorer.com/testnet/address/mx6WWrWgYHhHevB3KJqduRU8qpaopdWBJF

About 50 sends and 50 receives is quite a lot for the average user, but some 
power users might hit the limit soon.

I'll extend to 96 kb stack...

Original comment by andreas....@gmail.com on 5 Sep 2011 at 8:31

GoogleCodeExporter commented 9 years ago
Is increasing the stack size a viable medium-term workaround, or should the 
priority on this be increased?

Original comment by mi...@google.com on 14 Oct 2011 at 8:35

GoogleCodeExporter commented 9 years ago
I have pretty much no idea of how high stack size can be set on Android without 
side effects.

I'd rather increase priority; not having a stable and extendable wallet format 
is a blocker for several other enhancements as well:

- storing creation timestamps with keys/addresses (for more effective retreival 
of block chain)
- export/import/backup of wallet

Original comment by andreas....@gmail.com on 14 Oct 2011 at 8:51

GoogleCodeExporter commented 9 years ago
Issue #4 is already high priority.  I was just wondering if there's something 
quick we can do to improve the current serialization or if we should focus on 
#4.

Original comment by mi...@google.com on 14 Oct 2011 at 9:39

GoogleCodeExporter commented 9 years ago
Oh, it can be set to a megabyte and that should last a long time. Long chains 
of transactions should be rare in normal usage.

Serialization sucks, I know. We'll get to it eventually.

Original comment by hearn@google.com on 15 Oct 2011 at 4:22

GoogleCodeExporter commented 9 years ago
One user just hit this error at 108 incoming and 108 outgoing transactions with 
96 kb of stack.

Original comment by andreas....@gmail.com on 10 Nov 2011 at 2:10

GoogleCodeExporter commented 9 years ago
Miron has implemented protobuf serialization for the wallet, which should 
resolve this once users are upgraded.

Original comment by hearn@google.com on 11 Jan 2012 at 6:54