Skip to content
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

should i copy the void *in data out at the very beginning of the callback function? #3258

Open
pppaulpeter opened this issue Nov 1, 2024 · 5 comments

Comments

@pppaulpeter
Copy link

Hi Andy,

sometime i found the in data is corrupt inside the callback funtion

static int callback_websocket(struct lws *wsi, enum lws_callback_reasons reason,
                              void *user, void *in, size_t len) 

when i copy the in data at the very beginning of the callback function, the problem is solved, so in think the in data is corrupt somehow, it should not be my code since all my function will declear ''in'' as a ''const chat*''', could you help on this topic? thanks!
@lws-team

@lws-team
Copy link
Member

lws-team commented Nov 1, 2024

Where *in points to depends on the callback.

Sometimes, it uses a 'large' (several KB typ) common buffer that belongs to the wsi. This, for example, can be used to contain decoded ws RX for the RX callback, but since the wsi buffer allocation is valuable, it might also be used for http header creation etc. Typically you don't need to copy stuff out since what you will do with, eg, ws RX is not related to, eg, http headers on the same wsi.

If *in points into a specific lws-allocated buffer, the normal flow of things for a single-threaded event loop is the buffer can't be freed while you are in the callback and will continuously be valid from there, if it's going to be freed it will happen after you leave the callback and return to the event loop.

If you have threads, which can run while you are in the callback for a particular wsi, you cannot call any lws apis from that thread context except lws_cancel_service() from them, to ensure no lws state is changed while you are in the wsi callback in the lws thread. (If you have multi contexts on different service threads, you cannot directly touch wsi from one context in another for the same reason).

Before saying something is "corrupt" it's better to take a look at what was unexpectedly written there, and / or use valgrind to watch for problems, things are usually "overwritten by" something else specific, or use-after-freed, not simply "corrupted".

@pppaulpeter
Copy link
Author

overwritten by

yes, it was overwritten by other code since i can't parse the xml inside anymore, when i print it, the initial part is the same as before, i will check it later.

@lws-team
Copy link
Member

lws-team commented Nov 4, 2024

"valgrind" is the word you should take notice of in there. "Use after free" can look like corruption / overwrite if you are expecting it to not have been freed / reallocated.

@pppaulpeter
Copy link
Author

pppaulpeter commented Nov 6, 2024

"valgrind" is the word you should take notice of in there. "Use after free" can look like corruption / overwrite if you are expecting it to not have been freed / reallocated.

yes, i run it in embedded device, it is not easy to test it with valgrind. but i will try later.
i just print the ''in''' buffer , this is what i got
'''Nov 6 10:45:01 ---test Msg:<WSM_Request>AFE489B4-936B-43DF-91B5-2DD47663204CPOST /subscribeEvent</WSM_Request>
Nov 6 10:45:01 Origin: https://10.17.115.251^M
Nov 6 10:45:01 Sec-WebSocket-VersionHTTP/1.1 101 Switching Protocols^M
Nov 6 10:45:01 Upgrade: WebSocket^M
Nov 6 10:45:01 Connection: Upgrade^M
Nov 6 10:45:01 Sec-WebSocket-Accept: uJaTz/pDba3f4d1pG7DG8W4hHfw=^M
Nov 6 10:45:01 ^M'''
you are correct, http header and websocket text data are in the same buffer memory. thanks for your help!

@lws-team
Copy link
Member

lws-team commented Nov 7, 2024

Nothing stops you running the same code on, eg, linux, so you can get some confidence about stability under valgrind.

It's not very meaningful to just puts() *in without knowing the active length (or the callback involved), it will stop at the first NUL and there's nothing telling you if the data shown was already consumed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants