4.0.29 crash when listing files

I upgraded to 4.0.29 recently and using a custom config on Linux, and when I press a button for the interactive menues (interactive_switch_buffer, interactive_open) I get a segfault.

1
2
3
4
5
Thread 13 "4ed" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffaf6de700 (LWP 15536)]
0x00007fffb5146826 in lister_add_item (arena=0x7fffb51a7508 <global_lister_state_+14312>, lister=0x7fffb51a7518 <global_lister_state_+14328>, string=..., 
    status=..., user_data=0xf, extra_space=0) at /home/rytc/4coder/4coder_ui_helper.cpp:437
437        node->string = string.string;


Debugging stuff, hopefully it helps

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
(gdb) print node
$1 = (Lister_Node *) 0x10
(gdb) print node->string
Cannot access memory at address 0x20
(gdb) print string
$2 = {string = {str = 0x0, size = 0, memory_size = 0}}
(gdb) list
432	static void*
433	lister_add_item(Partition *arena, Lister *lister,
434	                Lister_Prealloced_String string, Lister_Prealloced_String status,
435	                void *user_data, int32_t extra_space){
436	    Lister_Node *node = push_array(arena, Lister_Node, 1);
437	    node->string = string.string;
438	    node->status = status.string;
439	    node->user_data = user_data;
440	    node->raw_index = lister->options.count;
441	    zdll_push_back(lister->options.first, lister->options.last, node);
(gdb) bt 
#0  0x00007fffb5146826 in lister_add_item (arena=0x7fffb51a7508 <global_lister_state_+14312>, lister=0x7fffb51a7518 <global_lister_state_+14328>, 
    string=..., status=..., user_data=0xf, extra_space=0) at /home/rytc/4coder/rytc_4coder/../4coder_ui_helper.cpp:437
#1  0x00007fffb5146ae0 in lister_add_item (arena=0x7fffb51a7508 <global_lister_state_+14312>, lister=0x7fffb51a7518 <global_lister_state_+14328>, 
    string=..., status=..., user_data=0xf, extra_space=0) at /home/rytc/4coder/rytc_4coder/../4coder_ui_helper.cpp:472
#2  0x00007fffb515c16f in generate_all_buffers_list__output_buffer (arena=0x7fffb51a7508 <global_lister_state_+14312>, 
    lister=0x7fffb51a7518 <global_lister_state_+14328>, buffer=...) at /home/rytc/4coder/rytc_4coder/../4coder_lists.cpp:461
#3  0x00007fffb515c44d in generate_all_buffers_list (app=0x7ffff5ef25f8, arena=0x7fffb51a7508 <global_lister_state_+14312>, 
    lister=0x7fffb51a7518 <global_lister_state_+14328>) at /home/rytc/4coder/rytc_4coder/../4coder_lists.cpp:509
#4  0x00007fffb515b818 in begin_integrated_lister__with_refresh_handler (app=0x7ffff5ef25f8, query_string=0x7fffb5187ee1 "Switch:", handlers=..., 
    user_data=0x0, user_data_size=0, view=0x7fffaf6dddb0) at /home/rytc/4coder/rytc_4coder/../4coder_lists.cpp:323
#5  0x00007fffb515cbfb in begin_integrated_lister__buffer_list (app=0x7ffff5ef25f8, query_string=0x7fffb5187ee1 "Switch:", 
    activate_procedure=0x7fffb515d193 <activate_switch_buffer(Application_Links*, Partition*, Heap*, View_Summary*, Lister_State*, String, void*, bool32)>, user_data=0x0, user_data_size=0, target_view=0x7fffaf6dddb0) at /home/rytc/4coder/rytc_4coder/../4coder_lists.cpp:600
#6  0x00007fffb515d28b in interactive_switch_buffer (app=0x7ffff5ef25f8) at /home/rytc/4coder/rytc_4coder/../4coder_lists.cpp:735
#7  0x00007fffb51b1f14 in command_caller (coroutine=<optimized out>) at /home/allen/4ed/code/4ed.cpp:696
#8  0x000000000040a7b7 in coroutine_main (ptr=0x7fffb50fb198) at /home/allen/4ed/code/platform_all/4ed_coroutine.cpp:83
#9  0x00007ffff7e50a9d in start_thread () from /usr/lib/libpthread.so.0
#10 0x00007ffff7445a43 in clone () from /usr/lib/libc.so.6
(gdb) print string
$4 = {string = {str = 0x0, size = 0, memory_size = 0}}
(gdb) print &string
$5 = (Lister_Prealloced_String *) 0x7fffaf6dd8c0
(gdb) print arena
$6 = (Partition *) 0x7fffb51a7508 <global_lister_state_+14312>
(gdb) print *arena
$7 = {base = 0x0, pos = 80, max = 65536}
(gdb) print sizeof(Lister_Node)
$8 = 64


Crash must be happening earlier because all of that looks relatively sane. I noticed that "init_memory(app)" doesn't exist anymore, so I assume its because there's a new way to init memory?


Valgrind output

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
==17625== Memcheck, a memory error detector
==17625== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==17625== Using Valgrind-3.14.0.GIT and LibVEX; rerun with -h for copyright info
==17625== Command: 4ed
==17625== 
==17625== Warning: set address range perms: large range [0x6d23000, 0x26d23000) (defined)
==17625== Warning: set address range perms: large range [0x26f23000, 0x46f23000) (defined)
==17625== Thread 13:
==17625== Invalid write of size 8
==17625==    at 0x47A94826: lister_add_item(Partition*, Lister*, Lister_Prealloced_String, Lister_Prealloced_String, void*, int) (4coder_ui_helper.cpp:437)
==17625==    by 0x47A94ADF: lister_add_item(Partition*, Lister*, String, String, void*, int) (4coder_ui_helper.cpp:472)
==17625==    by 0x47AAA16E: generate_all_buffers_list__output_buffer(Partition*, Lister*, Buffer_Summary) (4coder_lists.cpp:461)
==17625==    by 0x47AAA44C: generate_all_buffers_list(Application_Links*, Partition*, Lister*) (4coder_lists.cpp:509)
==17625==    by 0x47AA9817: begin_integrated_lister__with_refresh_handler(Application_Links*, char*, Lister_Handlers, void*, int, View_Summary*) (4coder_lists.cpp:323)
==17625==    by 0x47AAABFA: begin_integrated_lister__buffer_list(Application_Links*, char*, void (*)(Application_Links*, Partition*, Heap*, View_Summary*, Lister_State*, String, void*, int), void*, int, View_Summary*) (4coder_lists.cpp:600)
==17625==    by 0x47AAB28A: interactive_switch_buffer(Application_Links*) (4coder_lists.cpp:735)
==17625==    by 0x4782EF13: command_caller(Coroutine_Head*) (4ed.cpp:696)
==17625==    by 0x40A7B6: coroutine_main(void*) (4ed_coroutine.cpp:83)
==17625==    by 0x49AFA9C: start_thread (in /usr/lib/libpthread-2.28.so)
==17625==    by 0x53FFA42: clone (in /usr/lib/libc-2.28.so)
==17625==  Address 0x20 is not stack'd, malloc'd or (recently) free'd
==17625== 
==17625== 
==17625== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==17625==  Access not within mapped region at address 0x20
==17625==    at 0x47A94826: lister_add_item(Partition*, Lister*, Lister_Prealloced_String, Lister_Prealloced_String, void*, int) (4coder_ui_helper.cpp:437)
==17625==    by 0x47A94ADF: lister_add_item(Partition*, Lister*, String, String, void*, int) (4coder_ui_helper.cpp:472)
==17625==    by 0x47AAA16E: generate_all_buffers_list__output_buffer(Partition*, Lister*, Buffer_Summary) (4coder_lists.cpp:461)
==17625==    by 0x47AAA44C: generate_all_buffers_list(Application_Links*, Partition*, Lister*) (4coder_lists.cpp:509)
==17625==    by 0x47AA9817: begin_integrated_lister__with_refresh_handler(Application_Links*, char*, Lister_Handlers, void*, int, View_Summary*) (4coder_lists.cpp:323)
==17625==    by 0x47AAABFA: begin_integrated_lister__buffer_list(Application_Links*, char*, void (*)(Application_Links*, Partition*, Heap*, View_Summary*, Lister_State*, String, void*, int), void*, int, View_Summary*) (4coder_lists.cpp:600)
==17625==    by 0x47AAB28A: interactive_switch_buffer(Application_Links*) (4coder_lists.cpp:735)
==17625==    by 0x4782EF13: command_caller(Coroutine_Head*) (4ed.cpp:696)
==17625==    by 0x40A7B6: coroutine_main(void*) (4ed_coroutine.cpp:83)
==17625==    by 0x49AFA9C: start_thread (in /usr/lib/libpthread-2.28.so)
==17625==    by 0x53FFA42: clone (in /usr/lib/libc-2.28.so)
==17625==  If you believe this happened as a result of a stack
==17625==  overflow in your program's main thread (unlikely but
==17625==  possible), you can try to increase the size of the
==17625==  main thread stack using the --main-stacksize= flag.
==17625==  The main thread stack size used in this run was 8388608.
==17625== 
==17625== HEAP SUMMARY:
==17625==     in use at exit: 8,140,301 bytes in 54,612 blocks
==17625==   total heap usage: 111,933 allocs, 57,321 frees, 30,351,452 bytes allocated
==17625== 
==17625== LEAK SUMMARY:
==17625==    definitely lost: 2,440 bytes in 15 blocks
==17625==    indirectly lost: 354 bytes in 15 blocks
==17625==      possibly lost: 366,657 bytes in 2,468 blocks
==17625==    still reachable: 7,770,850 bytes in 52,114 blocks
==17625==                       of which reachable via heuristic:
==17625==                         newarray           : 349,056 bytes in 6 blocks
==17625==                         multipleinheritance: 16,128 bytes in 38 blocks
==17625==         suppressed: 0 bytes in 0 blocks
==17625== Rerun with --leak-check=full to see details of leaked memory
==17625== 
==17625== For counts of detected and suppressed errors, rerun with: -v
==17625== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
Segmentation fault (core dumped)



Edited by Ryan on Reason: Initial post
My guess is you want to look at 4coder_ui_helper.cpp:215:
1
int32_t arena_size = (64 << 10);


This was supposed to be replaced with an exact computation of arena size for all listers but apparently I missed some. If you have a lot of files then then memory set aside for widget data is just too small. You can just bump that 10 up by one at a time until it stops crashing. If it doesn't stop crashing by like (64 << 20) then probably something else went wrong.

Hope that helps.
Thanks for the tip, unfortunately it didn't seem to help. Even went up to << 25 and still crashed. I only have ~12 source files loaded in the project, ~30 files total in the project's directory.

EDIT: it seems to work fine with the default build (not my config code). I don't do anything with memory in my config, so there must be something I'm not initializing correctly?

EDIT2: actually it looks like none of my bindings are working, and I can't type text into the scratch buffer. Something must be very wrong with my config lol

Edited by Ryan on Reason: more info
Okay, looks like I may have fixed the crashing. Needed to add this to my start hook:

1
2
3
4
5
6
7
8
9
    int32_t part_size = (32 << 20);
    int32_t heap_size = ( 4 << 20);
    
    void *part_mem = memory_allocate(app, part_size);
    global_part = make_part(part_mem, part_size);
    
    void *heap_mem = memory_allocate(app, heap_size);
    heap_init(&global_heap);
    heap_extend(&global_heap, heap_mem, heap_size);



Ahh, in that case you should just call default_4coder_initialize(app). For one thing the code that initializes the global memory structures in the custom layer isn't the only thing you're missing out on by not calling this at startup, if you don't want all the features that are initialized in there, explain to me what you need and I can break down the API. Also, moving forward that init call may be necessary for some other future features which you'll have to initialize yourself everytime you upgrade and there's something new, unless you're calling the init function.
Yea, I ended up redoing my whole config...I saw that function and it looks like a lot of things in there are needed that I don't need to customize so I left it as-is.

As an aside: I had originally setup my config similar to how Casey has his. Now that we can setup multiple binding maps, it's much easier to setup modal bindings. My config is now MUCH cleaner and is simpler to manage and modify now. In the end, it was well worth redoing the config.