After running buildsuper.bat with my custom layer 4ed can't start. No error message given. (v. 4.0.26)

I have decided to write my keybindings in the "custom layer". I've done as you suggested in another thread and added a "my_bindings.cpp" file in the main directory of 4ed. Here's the code I added there:

  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
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
#include "4coder_default_include.cpp"

CUSTOM_COMMAND_SIG(switch_buffer_rot)
CUSTOM_DOC("Switches the buffer by rotating to the most recently used one. Useful if you're constantly changing between 2 different buffers.")
{
    Buffer_Summary next_buffer = {};
    
    get_buffer_next(app, &next_buffer, AccessHidden);
    View_Summary active_view = get_active_view(app, AccessOpen);
    
    view_set_buffer(app, &active_view,next_buffer.buffer_id, 0);
}

CUSTOM_COMMAND_SIG(kill_cur_buffer_and_rot)
CUSTOM_DOC("Kills the buffer in the current view, and opens the next buffer in its place")
{
    Buffer_Summary next_buffer = {};
    
    get_buffer_next(app, &next_buffer, AccessHidden);
    View_Summary active_view = get_active_view(app, AccessOpen);
    
    Buffer_Identifier buff_ident = {0, 0, active_view.buffer_id};
    
    kill_buffer(app, buff_ident, active_view.view_id, 0);
    view_set_buffer(app, &active_view,next_buffer.buffer_id, 0);
}

CUSTOM_COMMAND_SIG(seek_whitespace_or_inword_right)
CUSTOM_DOC("Seek right. If the word is camelCase, or snake_case, it'll seek until the next separator, or it'll just go until the end of the word.")
{ basic_seek(app, true, BoundaryAlphanumeric | BoundaryCamelCase | BoundaryWhitespace); }

CUSTOM_COMMAND_SIG(seek_whitespace_or_inword_left)
CUSTOM_DOC("Seek left. If the word is camelCase, or snake_case, it'll seek until the next separator, or it'll just go until the end of the word.")
{ basic_seek(app, false, BoundaryAlphanumeric | BoundaryCamelCase | BoundaryWhitespace); }

CUSTOM_COMMAND_SIG(seek_word_right)
CUSTOM_DOC("Seek right. Always reaches end of current word.")
{ basic_seek(app, true, BoundaryWhitespace); }

CUSTOM_COMMAND_SIG(seek_word_left)
CUSTOM_DOC("Seek left. Always reaches end of current word.")
{ basic_seek(app, false, BoundaryWhitespace); }

CUSTOM_COMMAND_SIG(move_buffer_other_panel)
CUSTOM_DOC("Moves buffer in active panel to other non-active panel, and switches current panel with next available buffer")
{ 
    swap_buffers_between_panels(app);
    switch_buffer_rot(app);
}

extern "C" int32_t get_bindings(void *data, int32_t size)
{
    Bind_Helper context_ = begin_bind_helper(data, size);
    Bind_Helper *context = &context_;
    
    set_all_default_hooks(context);
    /* Put all bindings here */
    bind(context, ' ', MDFR_CTRL, set_mark);
    bind(context, 'c', MDFR_CTRL, copy);
    bind(context, 'd', MDFR_CTRL, delete_range);
    bind(context, 'D', MDFR_CTRL, delete_line);
    bind(context, 'f', MDFR_CTRL, search);
    bind(context, 'F', MDFR_CTRL, list_all_locations);
    bind(context, 'F', MDFR_ALT, list_all_substring_locations_case_insensitive);
    bind(context, 'l', MDFR_CTRL , change_active_panel);
    bind(context, 'p', MDFR_CTRL , open_panel_vsplit);
    bind(context, 'p', MDFR_ALT ,  open_panel_hsplit);
    bind(context, 'k', MDFR_CTRL , close_panel);
    bind(context, 's', MDFR_CTRL , save);
    bind(context, 'S', MDFR_CTRL , save_all_dirty_buffers);
    bind(context, 'o', MDFR_CTRL , interactive_open_or_new);
    bind(context, 'O', MDFR_CTRL , open_in_other);
    bind(context, 'i', MDFR_CTRL , switch_buffer_rot);
    bind(context, 'I', MDFR_CTRL , interactive_switch_buffer);
    bind(context, 'n', MDFR_CTRL , interactive_new);
    bind(context, 'j', MDFR_CTRL , kill_cur_buffer_and_rot);
    bind(context, 'J', MDFR_CTRL , interactive_kill_buffer);
    bind(context, 'y', MDFR_CTRL, redo);
    bind(context, 'z', MDFR_CTRL, undo);
    
    bind(context, 'u', MDFR_CTRL , view_buffer_other_panel);
    bind(context, 'U', MDFR_CTRL , swap_buffers_between_panels);
    bind(context, 'u', MDFR_ALT , move_buffer_other_panel);
    bind(context, '.', MDFR_CTRL , open_matching_file_cpp);
    
    bind(context, key_right, MDFR_CTRL , seek_whitespace_or_inword_right);
    bind(context, key_left, MDFR_CTRL , seek_whitespace_or_inword_left);
    bind(context, key_right, MDFR_CTRL | MDFR_SHIFT , seek_word_right);
    bind(context, key_left, MDFR_CTRL | MDFR_SHIFT , seek_word_left);
    
    bind(context, key_up, MDFR_CTRL , seek_whitespace_up_end_line);
    bind(context, key_down, MDFR_CTRL , seek_whitespace_down_end_line);
    bind(context, key_up, MDFR_ALT , move_line_up);
    bind(context, key_down, MDFR_ALT , move_line_down);
    bind(context, key_back, MDFR_CTRL, backspace_word);
    bind(context, key_del, MDFR_CTRL, delete_word);
    bind(context, key_back, MDFR_ALT, snipe_token_or_word);
    bind(context, key_del, MDFR_ALT, snipe_token_or_word_right);
    
    bind(context, 'ù', MDFR_ALT , open_color_tweaker);
    
    int32_t result = end_bind_helper(context);
    return(result);
}


First of all, I couldn't even run the buildsuper.bat because the path of the 4ed directory contained a space in it:
"E:/Programming Utility/4coder"
It took me a while to make it work, but I'm pretty sure it's not your batch's fault, instead it's "vcvarsall.bat" fault...

Anyway, after successfully running buildsuper.bat without errors, trying to startup 4ed resulted in *nothing*. No error message, no process in the task manager, no window, absolutely nothing.
I don't know if it's my code's fault, or if I'm doing something wrong...

I understand that you're gonna change the customization system in the 4.1.0 release, but you should really consider spending just a couple hours adding one paragraph into your site on how to properly set up your own custom layer, or if it already exists, make it findable, because I couldn't find this information anywhere other than looking through the forums...

Edited by Lorenzo on Reason: Initial post
Yeah I agree, I need more help info... although this looks like something worse than that. As far as I can tell at you've done everything correctly, and even if there is a problem, it should manifest with an error window telling you what's wrong with the custom dll.

Try launching 4coder with -L (logging flag) and see if it generates a log file.

I'm also frustrated to find out that spaces in the path are still a problem, I thought that one was handled :/ I'll definitely take a careful look at the build process very soon.
Running with -L created this log file (I made sure to remove any previous log files)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
w:\4ed\code\platform_all\4ed_shared_init_logic.cpp:141:
Read command line.
w:\4ed\code\platform_all\4ed_shared_init_logic.cpp:121:
Loaded custom file: E:\ProgrammingUtility\4coder\custom_4coder.dll
w:\4ed\code\platform_win32\win32_4ed.cpp:1284:
Creating window... w:\4ed\code\platform_win32\win32_4ed.cpp:1296:
Success
w:\4ed\code\platform_win32\win32_4ed.cpp:764:
trying to load wgl extensions...
w:\4ed\code\platform_win32\win32_4ed.cpp:823:
got wgl functions
w:\4ed\code\platform_win32\win32_4ed.cpp:878:
successfully enabled opengl
w:\4ed\code\platform_win32\win32_4ed.cpp:1320:
Initializing fonts
w:\4ed\code\platform_win32\win32_4ed.cpp:1332:
Initializing clipboard
w:\4ed\code\platform_win32\win32_4ed.cpp:1365:
Got performance frequency 4.101571
w:\4ed\code\platform_win32\win32_4ed.cpp:1387:
Initializing application variables


Just as a good measure let's try adding a few more info:

Windows 10 Home Edition 64-bit (Version 1709, Build 16299.371)
Intel Core i7-7700k
16 GB RAM

4ed is currently NOT running from the operating system SSD, but from a secondary internal HHD I use to store programs.

I've just noticed windows has pending system updates at the time of testing and writing... I'll try installing the updates and see if anything changes...
Thanks for the log file. That's definitely too short which indicates it's crashing somewhere after "Initializing application variables" so later tonight I can probably zoom in on the issue with that information.
Okay so there are a few possibilities of what may be going wrong. I have two suggestions, it's fine if you do them in whatever order you like:

1. It could be that the 4coder core (4ed_app.dll) is out of sync with the windows runner (4ed.exe). This could have happened if you deleted 4ed_app.dll manually by accident, or if you manually copied two versions together, etc. If you think this might have happened, you can try just downloading fresh and making sure that the fresh download works. Then put in your code and try again to build it and run with it.

2. It could be that there's a mistake somewhere in the custom code that is leading to this crash that I am not realizing right now. To test this I have two proposals you can try either or both. One thing you could do is to use visual studio add 4ed.exe to a solution by itself, and then run it with debugging enabled. If you've got debug symbols for your custom code you might be able to see a crash happen there. Even without that you might find some clues in disassembly that I can use. The second option is to try to build the original custom layer again (just running buildsuper with no parameters), and see if 4coder launches correctly then.
Ok:

1.
Tried downloading it again. It ran correctly on the default settings. Once I applied the same custom layer, the same exact bug happened.

2.
The crash is happening inside a function in 4ed_app.dll. I tried stepping through the code from the very beginning looking at the assembly and it definately happens very early in the process. We're talking less than 100 instructions. I don't know if the Call Stack in visual studio during disassembly is reliable or not, but something that I found interesting is that it went from being inside 4ed.exe to executing a call op and suddenly being 4 levels deep, two levels inside the 4ed.exe and two levels inside 4ed_app.dll. I'll attach an image so it's clearer.

By the way, I've tried building again without my custom layer and 4ed works properly then. So it has to be something either in my code or my system that's confusing the program.


Ahh! It's hitting an assert! In release my asserts compile to mov dword ptr [0],0A11Eh so that I can recognize them in disassembly. (Hence A11E as in Allen :D) That should help actually, I'll take another look at the asserts in that area and figure out what you're hitting.
That's actually a pretty smart idea ahahah. Nice :D
Okay I have some theories, but first a couple questions:

1. Did you modify buildsuper.bat to make it work for your situation? If so could you post that?

2. When you were stepping through the code did you step into the calls (F11)? It might have suddenly gone several layers deep on the call stack if you stepped over the call and it broke in there while it was doing way more than just one instruction. If this might be what happened, you can try to put a break point in your "get_bindings" function just to make sure you stop in there when it starts executing. Since it doesn't break with the default DLL I suspect it must be getting into your code but I could be wrong.

3. You have one binding with an unusual character, have you tried removing it? If it is breaking right after getting bindings it is probably caused by something unusual in the binding data you're returning, and that's the most unusual part of your bindings.

Edited by Allen Webster on
1.
I did NOT modify the buildsuper.bat in the end. I gave up and removed the space in the path. I tested it a little bit, and modified it in the beginning, but as I said before, I'm pretty sure your batch passes arguments and strings correctly. It should be the vcvarsall.bat that breaks down.

Because of that I reverted the changes and testing I did on the buildsuper.bat. Just to make sure I checked it against a fresh copy of the program, and it was indeed the same.

2.
I tried putting a breakpoint in my_bindings.cpp. 4coder could step through it no problem. The bug happened shortly after. To be exact, right after returning from my code, it called into a 1° function -> called into a 2° function -> returned from the 2° function -> assert fired BEFORE exiting 1° function.

3.
The "weird" character is just a ù. I don't know why the forum's "code" tag mangled it. The editor shows it correctly.
I have an Italian keyboard layout, so that button is more comfortable for me to use than others. Anyway I tried to comment out that particular bind and it didn't change anything.

Edited by Lorenzo on
Don't special (meaning non-ascii, > 127) characters require get_key_code ?
1
bind(context, get_key_code("ù"), MDFR_ALT , open_color_tweaker);

And make sure the file is utf8 encoded.

Edited by Simon Anciaux on
The problem persisted even with that line commented out. Anyway I've added the "get_key_code()" call, just to be sure. How do I make sure the file is utf-8 encoded?
If you are editing it with 4coder it should be utf8.

Otherwise, open the file in Visual Studio, Save as... The save button should have a drop down menu with a "Save with encoding" option. In the encoding list choose "Unicode (UTF-8 without signature - Codepage 65001)". Make sure you use the "without" and not "with" signature.
Good news! I think I have figured it out. You need to put in "begin_map" "end_map" so that the keys you bind are actually bound to a specific map. I guess that triggers an assert when it should really trigger a warning message.

See for instance this snippet from "4coder_generated/remapping.h"

1
2
3
4
5
6
7
8
9
//...
begin_map(context, mapid_global);
bind(context, 'p', MDFR_CTRL, open_panel_vsplit);
bind(context, '_', MDFR_CTRL, open_panel_hsplit);
//...
bind(context, key_f15, MDFR_NONE, project_fkey_command);
bind(context, key_f16, MDFR_NONE, project_fkey_command);
end_map(context);
//...
That worked! Thank you for the help Allen :D and sorry for adding something new for you to fix :P