New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add libc initialisation code (was: Any cURL function crashes on Syllable) #129
Comments
Here's a GDb trace. I'm not sure it adds much to the kernel log crash trace.
|
This seems to be function is which many of the crashes happen: Could it be that the C library is not properly initialised? A trace of a natively compiled Syllable program shows that the C library is called first and then chains to the main entry point. Does Red follow this path? |
Yes, good guess. Red/System does not currently loop thru any platform-specific libc start mechanism, so that could be a possibility. |
To quickly test if libc startup really is causing the problem, you can chain thru
Adapt your libc soname accordingly, and move all other toplevel reds code into |
That was a good start, thanks for that. Here's a more correct version, with changes that make it work for Syllable. I think I've found a stack misalignment bug in Linux GLibC in the process. :-)
Syllable's interface for __libc_start_main is different from Linux. It doesn't pass argc and rtld-fini (the latter is also unused on Linux, anyway), but passes a pointer to env. It can't handle just a NULL for argv, probably because it computes argc from it. Here's our startup code: Most of the parameters are still incorrect. Proper startup code in Red is needed. A NULL for stack-end seems to work so far, but this can easily be set properly by machine code in Red. It's a misty matter what values should be used for init/fini. There are __libc_csu_init/__libc_csu_fini or alternatively _init/_fini symbols, but in many executables they're not defined. There are extra complications for PIC code, so we could leave this matter rest until we get into trouble over it. |
I understand that the issue is solved, so I am closing this ticket. |
How is it solved? The LibC initialisation code needs to be added. For all systems, but on Syllable it's somehow crititcal for cURL. We can add this workaround to all our programs, but that's very ugly, and system dependent. |
I have based my judgement on your sentence: Here's a more correct version, with changes that make it work for Syllable. which implies that the issue is solved for Syllable. If it is not the case, I will re-open it. If the issue changed to a wish, please open a new ticket describing the wish. |
It made the workaround work for Syllable, but that's not a solution for the issue that Red is lacking C library initialisation. To implement it properly, it needs machine code support in addition to the presented workaround. This issue started with the observation that the cURL binding crashes on Syllable and led to the conclusion that C library initialisation is missing in Red. Although we now have a workaround for cURL, that's only the third Red binding, so it is to be suspected that this issue will cause more problems in the future. I leave it to you whether that requires a new ticket. |
I am re-opening this ticket to try to clarify it, because I found it quite confusing. From this page, I can see what precisely does
|
Thanks for reopening. The subject is rather arcane, yes. I understand that it's ugly to add this to Red, because it feels like jumping through a hoop, but the point is that if one wants or at least needs to use the C library, the incantations the C library wants are required to make it work. The functions performed that are listed in the specification you linked are quite important. My guess is that "initialize the threading subsystem" is the one that currently crashes Syllable when it's not performed. This does not affect Red's logical model, only its implementation. That's also why I would like the above workaround to "disappear" into the runtime. Running Red's exit handler should not be a problem, because this is what the fini parameter is for. I haven't found another clear place yet where this parameter should come from, so it stands to reason that it can be used for your own exit handler. The argc and argv parameters, and env on Syllable, are already supported by Red now (which is why I split that off into another issue request). The remaining one that needs machine code support to set it properly is stack_end. |
I plan to add new stack manipulation native functions to Red/System, one of them will allow to retrieve stack top address (I guess this is what is meant by About Also, from what I see, My suggestion would be to research what are the libc init OS calls required by cURL and extract only those ones to put in the cURL wrapper init part. |
I really cannot agree with this. Red uses the C library, so it must interface properly with it. This is not optional. __libc_start_main is the documented way to do it for the GNU C library. You found the documentation for Linux yourself in the LSB standard. This has very little to do with cURL. cURL cannot do this initialisation. It is the other way around: the C library and the operating system do process initialisation between them that cURL happens to need, probably without knowing about it. |
This bug also affects the SDL binding, and now also the SQLite binding. |
This bug also affects the C math library binding. It stands to reason that it prevents any and all programs that use the C library, or another library that uses the C library, from working. Here's an updated version of the missing Red/System code:
I'm not sure this will establish the stack top correctly. |
For finding the proper stack top, one should walk through system/env-vars until |
For Linux,
That's all. :-) We need a way to import variables (like I would like to check for Syllable and Darwin if the requirements are similar. |
This would be a very dangerous way of implementing it, because as far as I can see, it's specific to the GNU C library. There are at least five different C libraries that I know of used on Linux, and it's also likely that the init code differs between different versions of the same library. Specific Linux distros may also have patched it. The method you describe for finding the stack top should work on Linux, but not on Syllable, because the arguments and the environment are stored on the heap there. See the link I gave earlier: That code is in addition to __libc_start_main and is similar to what happens on Linux. Here's our libc-start.c: |
Andreas proposed a draft but flexible solution on IRC, I need to dig it further to see if it could be implemented without causing too much trouble. Basically, we would add a new compilation directive (like #start) and pass it a platform-specific block of code containing a call to |
Yes, I also had something like that in mind. It would mirror the startup fragments needed in other compilers and C libraries. Instead of a directive (which is only used once) it could also be a file in a specific platform dependent place. |
Are the following functions always defined and exported?
If not, how we are supposed to deal with them? |
No, they're not always there. I haven't found where they should come from. |
I tested all the bindings that can work on Syllable and they work great now, except SDL sound playing now crashes, but that may be a different issue. |
The SDL issue you have might be related to issue #204. So, can we close this ticket now? |
I don't think the SDL issue is #204. It works on Linux and I'm fairly sure it once worked on Syllable. However, even if it turns out to be related to libc-init, we can make it a separate report. |
The Syllable SDL audio crash bug is in libc-init. It still works on faster-floats (although it uses 100% CPU). |
I don't have the SDL binding nor GDB installed on my Syllable image. If you can provide me step-by-step instructions to install them, I can have a quick look before the conf on Saturday, otherwise, we can look at it together next week in Amsterdam. |
SDL is included in Syllable. GDB is in the Developer's Delight package, but I'm not sure if it's completely functional: |
Thanks, I will try to install GDB then. |
We debugged this together and it turned out to be an issue in the Syllable SDL port that I forgot about, not in Red. |
Calling any cURL function results in a segfault or a cascade of segfaults. It doesn't seem to have to do with loading the library, because linking with cURL and then not calling its functions is OK. There's not much to compare with yet. On Syllable, the only other dynamic library binding is the C library, but I have no problem with that so far.
Here's the first segfault from the kernel log. It always seems to go like this, at address 0. If there are further segfaults, they tend to be at slightly higher and often increasing addresses.
The text was updated successfully, but these errors were encountered: