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

C api bug (strings not null-terminated) #577

Open
starlitxiling opened this issue Jul 5, 2024 · 10 comments
Open

C api bug (strings not null-terminated) #577

starlitxiling opened this issue Jul 5, 2024 · 10 comments
Labels
bug Something isn't working

Comments

@starlitxiling
Copy link
Contributor

When I use the C API, I find that some unpredictable id appear in read_dora_input_id, and it will be the same string I create after that. If I don't create it after that, it will be a segment of id plus a strange hexadecimal number (like BCAG). I think there is a pointer error phenomenon. I don't know if this is related to #540
12ff8c64e23d5bbef8f51c26de7bd50

@github-actions github-actions bot added the bug Something isn't working label Jul 5, 2024
@starlitxiling
Copy link
Contributor Author

if you want to reproduce my problem, you can refer this:https://github.com/dora-rs/autoware.universe/tree/feature/autoware_dora/tools/read_id_test

@XxChang
Copy link
Collaborator

XxChang commented Jul 8, 2024

Because String does not contain \0 char (nul terminator) which is very different from C-string.

You can push a '\0' at this line to see how these been changed.

impl From<String> for DataId {
fn from(id: String) -> Self {
Self(id)
}
}

 impl From<String> for DataId { 
     fn from(id: String) -> Self { 
         let mut id = id;
         id.push('\0');
         Self(id) 
     } 
 }

@XxChang
Copy link
Collaborator

XxChang commented Jul 9, 2024

by the way, please use strncmp for possibly null-terminator string instead of strcmp

@starlitxiling
Copy link
Contributor Author

 impl From<String> for DataId { 
     fn from(id: String) -> Self { 
         let mut id = id;
         id.push('\0');
         Self(id) 
     } 
 }

I tried this, but it fails when parsing dataflow.yml. I think pushing 0 directly will cause many problems.

@XxChang
Copy link
Collaborator

XxChang commented Jul 9, 2024

Or learn from
https://github.com/eclipse-zenoh/zenoh-c/blob/775e66586d105cbb42882ace58286f0cb2d967b2/src/commons.rs#L551-L568

I thing that let user release id-string is error-prone.

@phil-opp
Copy link
Collaborator

Only C uses null-terminated strings, all other languages (including C++) use length-terminated strings. So I don't think that we should force all other languages to reallocate their DataIds just so that things are more convenient for C.

The proper way to use strings returned by dora in C is to use length-aware functions (e.g. fwrite(id, id_len, 1, stdout)) . Alternatively, you can copy the ID into a new C-like string with null-termination (use malloc to allocate id_len + 1 bytes, then use strncpy` to copy the string).

If you're using the C-API from C++, you can simply do:

char *id_ptr;
size_t id_len;
read_dora_input_id(event, &id_ptr, &id_len);
std::string id(id_ptr, id_len);

I'm open to add convenience functions for these conversions to the API, but I don't think that we should change the From<String> for DataId implementation or do hidden mallocs.

What do you think?

@phil-opp phil-opp changed the title C api bug C api bug (strings not null-terminated) Jul 11, 2024
@starlitxiling
Copy link
Contributor Author

Thanks for your reply, I am not sure it is a good idea. When we get the Input_id in read_dora_input_id, we have already got a in unexpected input_id, like this:
image
So maybe user should specify the DataId len, such as if ( strncmp(id, "pointcloud",10) == 0) {}.

@starlitxiling
Copy link
Contributor Author

And there is a interesting phenomenon. we have a node which input_id is "pointcloud" and output_id is "pointcloud_no_ground". When we check the input_id of this node, sometimes its input_id is "pointcloud_no_ground". If we change output_id from "pointcloud_no_ground" to "no_ground", sometimes its input_id turn into "pointcloud1B0C168F5ACDF".

So there is a problem with DataId, I think maybe this a problem about C Thread-Safety api #540

@haixuanTao
Copy link
Collaborator

By re-reading those message it seems @starlitxiling is not using:

std::string id(id_ptr, id_len);

Such that it looks like this:

char *id_ptr;
size_t id_len;
read_dora_input_id(event, &id_ptr, &id_len);
std::string id(id_ptr, id_len)

Could you try to add this to the code?

As philipp mentioned, this should fix your problem

@starlitxiling
Copy link
Contributor Author

Ok,i will do this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants