-
Notifications
You must be signed in to change notification settings - Fork 151
libbpf-cargo: Relative anonymous type naming for struct fields #1178
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
base: master
Are you sure you want to change the base?
Conversation
Haven't looked at it yet, but this is great. I was considering doing that for |
Previously, anonymous types were named as __anon_{id} with id as a global counter. This approach caused cascading renaming of all subsequent anonymous definitions after any C anonymous struct order/amount change. This was a major design problem not for only development but even portability, since here may be the case when something was changed in vmlinux.h leading to compilation errors. This commit addresses the issue by localizing cascading effects to the local struct layer rather than the global layer. While the solution is not fully ideal - cascading still occurs within individual structs - it eliminates the need for wide Rust code modifications when the order of anonymous struct definitions changes. Note, that the commit does not fully eliminates __anon_{id}, but the most important part of it. The commit is breaking and should be included in major version update.
Here are still some plain __anon types like in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general this seems okay to me, but the code seems under documented and under-tested in the sense that I can remove/change various lines and all tests keep passing. Similarly, I am not sure I understand some of the assignments done. Left some comments.
libbpf-cargo/src/gen/btf.rs
Outdated
@@ -367,6 +368,13 @@ fn escape_reserved_keyword(identifier: Cow<'_, str>) -> Cow<'_, str> { | |||
} | |||
} | |||
|
|||
#[derive(Debug, Clone)] | |||
pub struct BtfDependency { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't have to be pub
, please restrict visibility. Same for fields.
libbpf-cargo/src/gen/btf.rs
Outdated
|
||
dependencies: RefCell<HashMap<TypeId, BtfDependency>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please add a doc comment describing the member?
libbpf-cargo/src/gen/btf.rs
Outdated
} | ||
|
||
impl TypeMap { | ||
pub fn derive_parent<'s>(&self, ty: &BtfType<'s>, parent: &BtfType<'s>) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pub fn derive_parent<'s>(&self, ty: &BtfType<'s>, parent: &BtfType<'s>) { | |
fn derive_parent<'s>(&self, ty: &BtfType<'s>, parent: &BtfType<'s>) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the name really fitting? Aren't you more registering a parent relationship rather than "deriving" anything?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assign_parent?
libbpf-cargo/src/gen/btf.rs
Outdated
dep.child_counter = Rc::new(RefCell::new(0)); | ||
} | ||
|
||
let parent_counter = Rc::<RefCell<i32>>::clone(&pdep.child_counter); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let parent_counter = Rc::<RefCell<i32>>::clone(&pdep.child_counter); | |
let parent_counter = Rc::clone(&pdep.child_counter); |
libbpf-cargo/src/gen/btf.rs
Outdated
if ty.name().is_some() { | ||
dep.child_counter = Rc::new(RefCell::new(0)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this code needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a comment
libbpf-cargo/src/gen/btf.rs
Outdated
if ty.name().is_some() { | ||
dep.child_counter = Rc::new(RefCell::new(0)); | ||
} | ||
dep.dep_id = 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this value set here and not already during initialization?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a comment
libbpf-cargo/src/gen/btf.rs
Outdated
if let Some(n) = parent.name() { | ||
dep.name = Some(n.to_string_lossy().to_string()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this value set here and not during initialization?
libbpf-cargo/src/gen/btf.rs
Outdated
pub name: Option<String>, | ||
pub dep_id: i32, | ||
pub child_counter: Rc<RefCell<i32>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please document what these represent.
What do you mean exactly? Where is "here"? |
In 0e504e6 I simplified the code slightly, modified the global anon counting behavior, added documentation for new structure fields and included a test for depth-aligned anonymous structs. The global anonymous struct counting now excludes relative anons to make its behavior more representative and easier to use. I also added some fallback protection on it for (im)possible case when global anonymous struct is assigned before a relative one: in such case we will use old type of naming.
Nvm. Those anonymous structs are at the global level and should be kept with old naming. I think the code is ok now, but I'm aware of possible name collisions for relative types. |
Previously, anonymous types were named as _anon{id} with id as a global counter. This approach caused cascading renaming of all subsequent anonymous definitions after any C anonymous struct order/amount change. This was a major design problem not for only development but even portability, since here may be the case when something was changed in vmlinux.h leading to compilation errors.
This PR addresses the issue by localizing cascading effects to the local struct layer rather than the global layer. While the solution is not fully ideal - cascading still occurs within individual structs - it eliminates the need for wide Rust code modifications when the order of anonymous struct definitions changes.
The PR is breaking and should be included in major version update.
The PR fixes #1161
While this approach is ok, I still think the better way will be to use getters, since this is breaking and less intuitive.