diff options
Diffstat (limited to 'doc/mono-gc.txt')
-rw-r--r-- | doc/mono-gc.txt | 445 |
1 files changed, 0 insertions, 445 deletions
diff --git a/doc/mono-gc.txt b/doc/mono-gc.txt deleted file mode 100644 index bc30334c5..000000000 --- a/doc/mono-gc.txt +++ /dev/null @@ -1,445 +0,0 @@ -The problem: - + mono is mind mangled & doesn't expose a sane GC API - + ie. it wants to know about your entire C stack & wander over it - + it should push/pop start/stop tags as we invoke in/out - + it should manage C handles with a controlled lifecycle - mechanism: ref/unref layered on top of the GC - => no need to worry about walking the C stack. - + however - this is horribly broken somehow. - -We really need something like GC_start_routine() - the start_info would be used to invoke our fn. and cleanup would - be automatic. - -* RedHerring 1: what is: - GC_push_all_stack(self, <base ptr>) - called from GCThreadFunctions mono_gc_thread_vtable - -> mono_gc_push_all_stacks - + for the debugger [ libgc/include/libgc-mono-debugger.h ] - - -* The pthread_support.c code seems to be not much called: - GC_segment_is_thread_stack - only from some dlopen code - GC_register_map_entries() [ filtering out code regions ? ] - - * seems to call GC_add_roots * - - /* Add a root segment. Wizards only. */ - GC_API void GC_add_roots GC_PROTO((char * low_address, - char * high_address_plus_1)); - /* Remove a root segment. Wizards only. */ - GC_API void GC_remove_roots GC_PROTO((char * low_address, - char * high_address_plus_1)); - - -* Adding a thread has to set the GC_suspend_handler / GC_restart_handler - + cf. pthread_stop_world, pthread_stop_init (?) - - + GC_stop_world uses the stop_world method from the vtable ... - GCThreadFunctions *gc_thread_vtable = &pthread_thread_vtable; - - => We need thread data to ensure we have stopped all the threads properly. - => we need to setup / install our signal handler properly in - each thread. - - + The high stack pointer is grokked from the - GC_approx_sp function - from the signal handler - just - returns cur ptr. - signal handler executing on stack of - signal recieving thread. [ fun ] - -* GC_push_all_stacks [ pthread_stop_world.c ] - + calls 'push_all_stack' for each thread. - + called from os_dep.c (GC_default_push_other_roots) - [ GC_push_other_roots ] - -* Hacking libgc: - -<lupus> yes, I suggest just duplicating the needed code for now -<michael_> lupus: is this a minimal-changes regimen ? or a wild-crazy-re-factoring-festival ? -<lupus> michael_: no crazy refactoring:-) -<michael_> lupus: and what does one do about a non-internal libgcj ? - or is that not a case worth worrying about ? -<lupus> michael_: we'll use the proper ifdef in the mono runtime -<michael_> sure - but it's ok to break horribly if we're not using an internal libgcj ? ;-) -<lupus> but a not internal gc is just for our testing, it's not a supported feature for people to use -<michael_> ie. no foreign-thread / OO.o impl. ? -<michael_> oh - great :-) - -** How does Mono get a callback from the pthread foo ? - + - -We need to add the functionality we need to mono_thread_attach - - -2005-04-12 log: - -<michael_> lupus: so - are you utterly opposed to adding this to mono_runtime_invoke ? -<lupus> michael_: why should I be opposed? -<michael_> lupus: there is a small cost, particularly if you don't have a thread-variable, -<michael_> lupus: of course - then we could bin the mono_thread_attach or whatever; -<lupus> michael_: unmanaged->managed is not an important transition and a simple check is cheap -<lupus> of course there is no need to drop mono_thread_attach -<michael_> lupus: ok'y dokey, -<michael_> lupus: so - I'll re-work the patch to move this code into mono_runtime_invoke ? -<lupus> michael_: if your current patch works for you, I can write the equivalent code for the next mono release -<lupus> we're not going to remove the thread info at the end of _invoke -<lupus> something like the setspecific hack you had may be enough -<michael_> lupus: the problem is - we could get invoked again from lower down the stack in the same thread trivially. -<michael_> lupus: so - it's really no safer; -<michael_> lupus: and removing the thread information from the gc post invoke - [ if we added it ourself ] is cheap anyhow. -<lupus> that is not cheap, it requires locking both in the runtime and the GC -<lupus> I don't see what removing the info each time buys us -<michael_> lupus: consider A() -> B() -> C() -> runtime_invoke -> adds stack base --><-- ---> eno (~atsushi@east94-p4.eaccess.hi-ho.ne.jp) has joined #mono -<lupus> the code I have in mind will check the stack start registered: if it doesn't contain the current stack address, we change it -<michael_> lupus: subsequently A() -> runtime_invoke -> stack base is now --><-- -<michael_> lupus: sounds fine, -<lupus> it will also register an aligned address -<michael_> lupus: sounds fine, -<lupus> at a page size so hopefully we get a good enough approximation of the thread start -<michael_> lupus: sounds like you've got it under control anyhow -<michael_> clearly manipulating the local thread stack/state should require precisely no locking in an ideal world ;-) -<michael_> but ... -<michael_> [ when we write a better GC - we'll make it perfectly precise - right ? ;-] -<lupus> michael_: since you need to register the thread with the GC it's not possible to avoid a lock, since it's global state -<lupus> and we won't have a perfectly precise GC -<michael_> lupus: AFAICS the GC only asks for that when a signal is fired, -<lupus> the unamanged stack will still be conservatively scanned for a while -<lupus> michael_: the GC needs the stack boundaries when doing collection -<michael_> lupus: I appreciate that ;-) -<michael_> lupus: anyhow - thanks for taking that on. -<michael_> lupus: when is the next release ? :-) -<lupus> michael_: likely in a month or so - - - - ---------------------- Debugging my bogus (non)-GC related bug --------------------- - -0x8240e70 - - + Threads created outside Mono's control ... - + GC crash - under gdb: - + greatest_ha - -(gdb) p limit -$1 = (word *) 0x83c2104 -(gdb) p *limit -Cannot access memory at address 0x83c2104 -(gdb) p *(limit - 4096) -$2 = 0 -(gdb) p *(limit + 4096) -Cannot access memory at address 0x83c6104 - - GC_mark_from mis-calculates limit, clearly it's scanning a -broken / non-object; missing the length [ with 0 bottom 2 bits] tag / -marker. Who sets that up ? - - The mark stack is a simple array, and looks fine ( in places ): - -$42 = {mse_start = 0x81fd800, mse_descr = 1024} -(gdb) p mark_stack[14] -$43 = {mse_start = 0x81eff00, mse_descr = 32} -(gdb) p mark_stack[15] -$44 = {mse_start = 0x81eef00, mse_descr = 160} -(gdb) p mark_stack[16] -$45 = {mse_start = 0x81fae00, mse_descr = 4294967279} -... <identical > ... -(gdb) p mark_stack[20] -$52 = {mse_start = 0x8355000, mse_descr = 4294967279} -(gdb) p mark_stack[21] -$53 = {mse_start = 0x83c2108, mse_descr = 136027216} -(gdb) p mark_stack[22] -$54 = {mse_start = 0x83acd20, mse_descr = 80} -(gdb) p mark_stack[23] -$55 = {mse_start = 0x83accd0, mse_descr = 80} - - The mark stack data comes from: MARK_FROM_MARK_STACK - - GC_mark_stack_top = GC_mark_from(GC_mark_stack_top, \ - GC_mark_stack, \ - GC_mark_stack + GC_mark_stack_size); - - + need to watch all manipulations of the GC_mark_stack ... (?) - gc_pmark.h - + GC_PUSH_ONE_HEAP, GC_PUSH_ONE_STACK (calls) - -> GC_mark_and_push, GC_mark_and_push_stack - - The problem comes from: GC_push_all_stacks ... (pthread_stop_world.c) - -#1 0x080fbe2b in GC_push_all_eager (bottom=0xbfffc1b4 "0%G���%@", top=0xbfffce30 "\002") at mark.c:1485 -#2 0x0813a7eb in pthread_push_all_stacks () at pthread_stop_world.c:260 -#3 0x0813a6ad in GC_push_all_stacks () at pthread_stop_world.c:291 -#4 0x080f673b in GC_push_roots (all=1, cold_gc_frame=0xbfffc254 "\200") at mark_rts.c:643 -#5 0x080fd0ea in GC_mark_some (cold_gc_frame=0xbfffc254 "\200") at mark.c:306 -#6 0x080ff51c in GC_stopped_mark (stop_func=0x80febe0 <GC_never_stop_func>) at alloc.c:533 -#7 0x080ff7d8 in GC_try_to_collect_inner (stop_func=0x80febe0 <GC_never_stop_func>) at alloc.c:375 -#8 0x080ff98d in GC_collect_or_expand (needed_blocks=1, ignore_off_page=0) at alloc.c:1035 -#9 0x080ffe23 in GC_allocobj (sz=128, kind=0) at alloc.c:1112 -#10 0x080f9041 in GC_generic_malloc_inner (lb=454, k=0) at malloc.c:136 -#11 0x080f90b4 in GC_generic_malloc (lb=454, k=0) at malloc.c:192 -#12 0x080f9361 in GC_malloc_atomic (lb=454) at malloc.c:270 -#13 0x080c226a in mono_string_new_size (domain=0x81eef00, len=220) at object.c:2081 -#14 0x080d1c18 in ves_icall_System_String_InternalAllocateStr (length=220) at string-icalls.c:634 - - * pthread_stop_world.c - do we set p->flags & MAIN_THREAD ? - + bs_lo = p->backing_store_end - + bs_hi = GC_save_regs_in_stack etc. - - * GC_push_all_eager - must get the wrong end of the stick somehow (?) - -initially (fine): - -Pushing stacks from thread 0x4021abc0 -Stack for thread 0x4021abc0(0x6) = [bfffcd64,bfffd0b0) - -later (broken): - -Pushing stacks from thread 0x4021abc0 -Stack for thread 0x40b01bb0(0x2) = [40b01594,40b02000) -Stack for thread 0x4021abc0(0x6) = [bfffc434,bfffd0b0) - - hi < lo etc. [!]... - - + How does MAIN_THREAD get set (?) - - surely correct (by Mono) - - + Header from pointer: GET_HDR()... GC_find_header(p) - - hdr * GC_find_header(h) ptr_t h; - + does return HDR_INNER(h) - -# define HDR_FROM_BI(bi, p) \ - ((bi)->index[((word)(p) >> LOG_HBLKSIZE) & (BOTTOM_SZ - 1)]) -# ifndef HASH_TL -# define BI(p) (GC_top_index \ - [(word)(p) >> (LOG_BOTTOM_SZ + LOG_HBLKSIZE)]) -# define HDR_INNER(p) HDR_FROM_BI(BI(p),p) - - -# define LOG_BOTTOM_SZ 10 -# define BOTTOM_SZ 1<<10 -# define LOG_HBLKSIZE 12 - - By instrumenting hb_descr setting with: - -Set hb_descr to 16 on hdr 0x81eed70 -Set hb_descr to -17 on hdr 0x81efe08 - -#0 setup_header (hhdr=0x81efe08, sz=4, kind=4, flags=0 '\0') at allchblk.c:243 -#1 0x080fc1e5 in GC_allochblk_nth (sz=4, kind=4, flags=0 '\0', n=6) at allchblk.c:743 -#2 0x080fbd78 in GC_allochblk (sz=4, kind=4, flags=0) at allchblk.c:558 -#3 0x081018a9 in GC_new_hblk (sz=4, kind=4) at new_hblk.c:253 -#4 0x081013d0 in GC_allocobj (sz=4, kind=4) at alloc.c:1103 -#5 0x080f94f6 in GC_generic_malloc_inner (lb=12, k=4) at malloc.c:136 -#6 0x080ff9c6 in GC_gcj_malloc (lb=12, ptr_to_struct_containing_descr=0x81b3b38) at gcj_mlc.c:157 -#7 0x080fa20b in GC_local_gcj_malloc (bytes=12, ptr_to_struct_containing_descr=0x81b3b38) at pthread_support.c:387 -#8 0x080c1117 in mono_object_new_alloc_specific (vtable=0x81b3b38) at object.c:2089 -#9 0x080c127b in mono_object_new_specific (vtable=0x81b3b38) at object.c:2147 -#10 0x080af01f in mono_type_get_object (domain=0x81f0f00, type=0x81c7e34) at reflection.c:5381 -#11 0x080c2094 in mono_class_vtable (domain=0x81f0f00, class=0x81c7d88) at object.c:861 -#12 0x080c20ca in mono_class_vtable (domain=0x81f0f00, class=0x81c7cb8) at object.c:859 -#13 0x080c20ca in mono_class_vtable (domain=0x81f0f00, class=0x81c7be8) at object.c:859 -#14 0x080c3223 in mono_object_new (domain=0x81f0f00, klass=0x81c7be8) at object.c:2108 -#15 0x080af01f in mono_type_get_object (domain=0x81f0f00, type=0x81c550c) at reflection.c:5381 -#16 0x080c2094 in mono_class_vtable (domain=0x81f0f00, class=0x81c5460) at object.c:861 -#17 0x080c20ca in mono_class_vtable (domain=0x81f0f00, class=0x81cc9a0) at object.c:859 -#18 0x080c3223 in mono_object_new (domain=0x81f0f00, klass=0x81cc9a0) at object.c:2108 -#19 0x080a7a1f in mono_runtime_init (domain=0x81f0f00, start_cb=0x81036b0 <mono_thread_start_cb>, - attach_cb=0x8103760 <mono_thread_attach_cb>) at appdomain.c:96 -#20 0x081053cd in mini_init (filename=0xbfffd37d "ViewSample.exe") at mini.c:10053 -#21 0x0805b99b in mono_main (argc=2, argv=0xbfffce24) at driver.c:837 -#22 0x0805b218 in main (argc=2, argv=0xbfffce24) at main.c:6 - - So: - -(gdb) p GC_obj_kinds[kind].ok_descriptor -$3 = 4294967279 -(gdb) p GC_obj_kinds[kind] -$4 = {ok_freelist = 0x81f4000, ok_reclaim_list = 0x8223000, ok_descriptor = 4294967279, ok_relocate_descr = 0, ok_init = 1} -(gdb) p kind -$5 = 4 - - Clearly ok_descriptor must be valid ... - do we not use this -as a size ? - allchblk.c (setup_header): - descr = GC_obj_kinds[kind].ok_descriptor; - if (...) descr += WORDS_TO_BYTES(sz); - - PUSH_OBJ(obj,hhdr) -> sets mse_descr to _descr - - Is this: - GC_obj_kinds[NORMAL].ok_descriptor = ((word)(-ALIGNMENT) | GC_DS_LENGTH); - responsible !? - -/* Predefined kinds: */ -# define PTRFREE 0 -# define NORMAL 1 -# define UNCOLLECTABLE 2 -# ifdef ATOMIC_UNCOLLECTABLE -# define AUNCOLLECTABLE 3 -# define STUBBORN 4 -# define IS_UNCOLLECTABLE(k) (((k) & ~1) == UNCOLLECTABLE) -# else -# define STUBBORN 3 -# define IS_UNCOLLECTABLE(k) ((k) == UNCOLLECTABLE) -# endif - -GC_new_kind_inner screwed up -17 - -Program received signal SIGSEGV, Segmentation fault. -[Switching to Thread 1075948480 (LWP 8355)] -GC_new_kind_inner (fl=0x81f4000, descr=4294967279, adjust=0, clear=1) at misc.c:1128 -1128 *(int *)NULL = 0; -(gdb) bt -#0 GC_new_kind_inner (fl=0x81f4000, descr=4294967279, adjust=0, clear=1) at misc.c:1128 -#1 0x080ff8f8 in GC_init_gcj_malloc (mp_index=5, mp=0x0) at gcj_mlc.c:87 -#2 0x080c1886 in mono_class_compute_gc_descriptor (class=0x81cc9a0) at object.c:539 -#3 0x080c1a77 in mono_class_vtable (domain=0x81f0f00, class=0x81cc9a0) at object.c:695 -#4 0x080c3223 in mono_object_new (domain=0x81f0f00, klass=0x81cc9a0) at object.c:2108 -#5 0x080a7a1f in mono_runtime_init (domain=0x81f0f00, start_cb=0x8103720 <mono_thread_start_cb>, - attach_cb=0x81037d0 <mono_thread_attach_cb>) at appdomain.c:96 -#6 0x0810543d in mini_init (filename=0xbfffd37d "ViewSample.exe") at mini.c:10053 -#7 0x0805b99b in mono_main (argc=2, argv=0xbfffce24) at driver.c:837 -#8 0x0805b218 in main (argc=2, argv=0xbfffce24) at main.c:6 -(gdb) - - So - I hypothesize - the kinds are meant to be big/negative - but this is -compensated for by the size of the allocation. - - GC_gcj_kind = GC_new_kind_inner( - (void **)GC_gcjobjfreelist, - (((word)(-MARK_DESCR_OFFSET - GC_INDIR_PER_OBJ_BIAS)) - | GC_DS_PER_OBJECT), - FALSE, TRUE); - - - export GC_IGNORE_GCJ_INFO=1 - and it works ... - - My gamble on GC_gcj_kind being broken ... - - The problem comes from: - -(gdb) bt -#0 setup_header (hhdr=0x81efe08, sz=4, kind=4, flags=0 '\0') at allchblk.c:245 -#1 0x080fc1ed in GC_allochblk_nth (sz=4, kind=4, flags=0 '\0', n=6) at allchblk.c:744 -#2 0x080fbd80 in GC_allochblk (sz=4, kind=4, flags=0) at allchblk.c:559 -#3 0x081018fd in GC_new_hblk (sz=4, kind=4) at new_hblk.c:253 -#4 0x08101424 in GC_allocobj (sz=4, kind=4) at alloc.c:1103 -#5 0x080f94f6 in GC_generic_malloc_inner (lb=12, k=4) at malloc.c:136 -#6 0x080ffa1a in GC_gcj_malloc (lb=12, ptr_to_struct_containing_descr=0x81b3b38) at gcj_mlc.c:157 -#7 0x080fa20b in GC_local_gcj_malloc (bytes=12, ptr_to_struct_containing_descr=0x81b3b38) at pthread_support.c:387 -#8 0x080c1117 in mono_object_new_alloc_specific (vtable=0x81b3b38) at object.c:2089 -#9 0x080c127b in mono_object_new_specific (vtable=0x81b3b38) at object.c:2147 -#10 0x080af01f in mono_type_get_object (domain=0x81f0f00, type=0x81c7e34) at reflection.c:5381 -#11 0x080c2094 in mono_class_vtable (domain=0x81f0f00, class=0x81c7d88) at object.c:861 -#12 0x080c20ca in mono_class_vtable (domain=0x81f0f00, class=0x81c7cb8) at object.c:859 -#13 0x080c20ca in mono_class_vtable (domain=0x81f0f00, class=0x81c7be8) at object.c:859 -#14 0x080c3223 in mono_object_new (domain=0x81f0f00, klass=0x81c7be8) at object.c:2108 -#15 0x080af01f in mono_type_get_object (domain=0x81f0f00, type=0x81c550c) at reflection.c:5381 -#16 0x080c2094 in mono_class_vtable (domain=0x81f0f00, class=0x81c5460) at object.c:861 -#17 0x080c20ca in mono_class_vtable (domain=0x81f0f00, class=0x81cc9a0) at object.c:859 -#18 0x080c3223 in mono_object_new (domain=0x81f0f00, klass=0x81cc9a0) at object.c:2108 -#19 0x080a7a1f in mono_runtime_init (domain=0x81f0f00, start_cb=0x8103700 <mono_thread_start_cb>, - attach_cb=0x81037b0 <mono_thread_attach_cb>) at appdomain.c:96 -#20 0x0810541d in mini_init (filename=0xbfffd37d "ViewSample.exe") at mini.c:10053 -#21 0x0805b99b in mono_main (argc=2, argv=0xbfffce24) at driver.c:837 -#22 0x0805b218 in main (argc=2, argv=0xbfffce24) at main.c:6 -(gdb) up - - So - then - negative hb_descrs are to be expected (apparently). - -process slot: 27 - DS_PER_OBJECT: 0xffffffef - Object of type 'MonoType' has size 536870913 - DS_BITMAP: 0x20000001 -process slot: 26 - DS_PER_OBJECT: 0xffffffef - Object of type 'XModel' has size 138021856 - DS_LENGTH: 0x83a0be0 -Assertion failure: mark.c:658 -assertion failure - - ... - -(gdb) p mark_stack_top -$1 = (mse *) 0x81e50d0 -(gdb) p *mark_stack_top -$2 = {mse_start = 0x8240e70, mse_descr = 4294967279} -(gdb) p *mark_stack_top->mse_start -$3 = 137267600 -(gdb) p *(MonoVTable **)mark_stack_top->mse_start -$4 = (struct MonoVTable *) 0x82e8990 -(gdb) p *$4 -$5 = {klass = 0x8398d38, gc_descr = 0x8398ec0, domain = 0x83a0bc0, interface_offsets = 0x83a0ce8, data = 0x0, type = 0x81fffa0, - max_interface_id = 34, rank = 0 '\0', remote = 0, initialized = 1, vtable = 0x82e89ac} -(gdb) p *$4->klass -$6 = {image = 0x8225010, enum_basetype = 0x0, element_class = 0x8398d38, cast_class = 0x8398d38, rank = 0 '\0', inited = 1, - init_pending = 0, size_inited = 1, valuetype = 0, enumtype = 0, blittable = 1, unicode = 0, wastypebuilder = 0, min_align = 1, - packing_size = 0, ghcimpl = 0, has_finalize = 0, marshalbyref = 0, contextbound = 0, delegate = 0, gc_descr_inited = 1, has_cctor = 0, - dummy = 0, has_references = 0, has_static_refs = 0, declsec_flags = 0, exception_type = 0, exception_data = 0x0, parent = 0x0, - nested_in = 0x0, nested_classes = 0x0, type_token = 33554953, name = 0x40b62892 "XModel", - name_space = 0x40b62899 "unoidl.com.sun.star.frame", supertypes = 0x83a1988, idepth = 1, interface_count = 1, interface_id = 72, - max_interface_id = 72, interface_offsets = 0x8397128, interfaces = 0x8352e28, instance_size = 8, class_size = 0, vtable_size = 0, - flags = 161, field = {first = 911, last = 911, count = 0}, method = {first = 1137, last = 1148, count = 11}, property = {first = 0, - last = 0, count = 0}, event = {first = 0, last = 0, count = 0}, marshal_info = 0x0, fields = 0x0, properties = 0x0, events = 0x0, - methods = 0x83985d8, this_arg = {data = {klass = 0x8398d38, type = 0x8398d38, array = 0x8398d38, method = 0x8398d38, - generic_param = 0x8398d38, generic_class = 0x8398d38}, attrs = 0, type = 18, num_mods = 0, byref = 1, pinned = 0, - modifiers = 0x8398de4}, byval_arg = {data = {klass = 0x8398d38, type = 0x8398d38, array = 0x8398d38, method = 0x8398d38, - generic_param = 0x8398d38, generic_class = 0x8398d38}, attrs = 0, type = 18, num_mods = 0, byref = 0, pinned = 0, - modifiers = 0x8398dec}, generic_class = 0x0, generic_container = 0x0, reflection_info = 0x0, gc_descr = 0x0, - runtime_info = 0x82470a0, vtable = 0x0} -(gdb) p mono_class_get_parent($4->klass) -$7 = (MonoClass *) 0x0 -(gdb) - -with: - -(gdb) p fprintf(stderr, "0x%x\n", 137989824) -0x8398ec0 - - ie. the gc_descr looks dead wrong. - - - ** Frighteningly the gc_descr points to another MonoClass - instead of a GC value [!?] - - With more debug printout we see: - -Add interface 'XComponentContext' -Set pvt->gc_descr to 0x30000001: vtable 0x82e8888 -... - Object of type 'TransparentProxy' vtable 0x82e8888 class 0x81cd9d0 currentp 0x8240e70 has size 805306369 slot 29 on stack - DS_BITMAP: 0x30000001 -... - Object of type 'XModel' vtable 0x82e8888 class 0x838a538 currentp 0x8240e70 has size 137930328 slot 26 on stack - DS_LENGTH: 0x838a658 - - The instance seems to change type [!?] - - Break in: - -Hardware watchpoint 3: *$3 - -Old value = (MonoClass *) 0x81cd9d0 -New value = (MonoClass *) 0x838a538 -0x080c1545 in mono_upgrade_remote_class (domain=0x81f5f00, remote_class=0x82bdbd0, klass=0x838a538) at object.c:1108 -1108 remote_class->interfaces [remote_class->interface_count-1] = klass; -(gdb) bt -#0 0x080c1545 in mono_upgrade_remote_class (domain=0x81f5f00, remote_class=0x82bdbd0, klass=0x838a538) at object.c:1108 -#1 0x0809506a in mono_upgrade_remote_class_wrapper (rtype=0x7, tproxy=0x836c120) at marshal.c:6806 - -From TransparentProxy -> XModel - -... - -Then - trampling all over the GC data: - -Hardware watchpoint 2: *$2 - -Old value = (void *) 0x30000001 -New value = (void *) 0x838a658 -0x080c1545 in mono_upgrade_remote_class (domain=0x81f5f00, remote_class=0x82bdbd0, klass=0x838a658) at object.c:1108 -1108 remote_class->interfaces [remote_class->interface_count-1] = klass; -(gdb) bt -#0 0x080c1545 in mono_upgrade_remote_class (domain=0x81f5f00, remote_class=0x82bdbd0, klass=0x838a658) at object.c:1108 -#1 0x080c4563 in mono_object_isinst_mbyref (obj=0x837ecd8, klass=0x838a658) at object.c:2862 -#2 0x080c655e in ves_icall_type_IsInstanceOfType (type=0x8, obj=0x837ecd8) at icall.c:1189 - |