Re: avoiding pitfal of reuse of globals in FLAT mode?

2021-03-23 Thread Xiang Xiao
On Wed, Mar 24, 2021 at 9:18 AM Matias N.  wrote:

>
>
> On Tue, Mar 23, 2021, at 22:09, Nathan Hartman wrote:
> > On Tue, Mar 23, 2021 at 8:39 PM Matias N.  matias%40imap.cc>> wrote:
> >
> > > Hi,
> > > while using getopt() from a task started from NSH I realized subsequent
> > > calls reused the global optind and similar variables resulting in
> different
> > > results each time. I'm aware this is expected in FLAT mode and is
> related
> > > to the issue of static C++ constructors (they would only be called
> once,
> > > not every time the task is started).
> > >
> > > What I wonder is what could we do to avoid this common pitfall:
> > > - document it somewhere (a common issues/troubleshooting section in the
> > > docs would be good to have anyways) and just accept the issue
>

Wiki already mention this issue here:
https://cwiki.apache.org/confluence/display/NUTTX/Linux+Processes+vs+NuttX+Tasks
Greg shares many knowledge in wiki. To improve the visibility, it's better
to migrate Confluence to Documentation.

> > - religiously initialize globals myself before being used (a pain, error
> > > prone, and a bit adhoc, working only for FLAT mode)
>
> > - support reentrant versions of all possible APIs and always use these
> in FLAT mode


Yes, it's the right direction to promote the reentrant API.


> > > - devise a mechanism to mimic what would be done by OS in KERNEL mode
> (add
>
> > some custom handler to APIs internally using globals, such as getopt,
> that can be
>
> > called either manually by user or by the OS itself when the task is
> started?)


The custom handler isn't enough here, because the real problem is we need
the global variables per task/process.
As Greg suggests, we need something like TLS but per task/process not per
thread(e.g. task_getspecific/task_setspecific).
Once the mechanism is done, getopt can be converted to confirm the standard
trivally.


>
> > - other?


The transparent/standard solution is switched to the ELF binary(note: it
doesn't depend on KERNEL mode), and then loses the XIP benefit(huge memory
penalty). But, it's doable to XIP again by combining ELF loader and ROMFS.


> >
> >
> > When using globals, best practice is to make it really clear that the
> > variables are global. Many programmers do this by prefixing global
> variable
> > names with g_*.
> >
> > I take a different approach: A long time ago, I started grouping all
> > globals in a struct, which has one global instance called Global. It
> makes
> > it easy to find all globals, and furthermore at the start of the program
> as
> > a matter of policy the first thing I do is memset() the Global struct to
> 0.
> > Yes, I know that is often redundant to the startup code, but in some
> > situations the startup code doesn't initialize globals. The FLAT model is
> > one example of this (from the 2nd invocation onwards). I've seen other
> > examples of this over the years. By memset()ing your globals at the start
> > of main() you can rest assured that the globals are in fact zeroed,
> > regardless of whatever else happened before main(). It has another side
> > benefit: with globals grouped this way, it becomes trivial to take a
> > standalone program and turn it into a component of a larger program.
> > tl;dr, this
> > approach has worked great for me for a long time.
>
> That sounds like a good approach.
>
> >
> > Caveat: It won't help if your program (or any API called by it) uses
> > globals that are outside your control, and therefore, not initialized by
> > you. :-/
>
> Yes, my concern is about functions such as getopt(). If you just follow the
> description of the API and use it as normal you reach this pitfall. I was
> looking
> for some approach to avoid this as much as possible. For getopt() I see
> there's
> even no standard getopt_r(), so we would have to provide our own, which
> may not
> be a bad idea.
> Still, this issue will probably present in many other places.
>
>
Seldom people will call getopt_r in Linux, because the different process
gets the new and clean copy, but it is crucial for NuttX to work correctly.
Yes, getopt_r isn't standardized by committee, but it follows the
convention used by other similar functions(e.g. strtok_r) and implemented
by glibc.

>
> > Nathan
> >
>
> Best,
> Matias


Re: avoiding pitfal of reuse of globals in FLAT mode?

2021-03-23 Thread spudaneco
One option is to replace the globals with accessor functions and use TLS to 
hold the actua. data.Sent from my Galaxy
 Original message From: "Matias N."  Date: 
3/23/21  7:18 PM  (GMT-06:00) To: dev@nuttx.apache.org Subject: Re: avoiding 
pitfal of reuse of globals in FLAT mode? On Tue, Mar 23, 2021, at 22:09, Nathan 
Hartman wrote:> On Tue, Mar 23, 2021 at 8:39 PM Matias N. mailto:matias%40imap.cc>> wrote:> > > Hi,> > while using getopt() from a task 
started from NSH I realized subsequent> > calls reused the global optind and 
similar variables resulting in different> > results each time. I'm aware this 
is expected in FLAT mode and is related> > to the issue of static C++ 
constructors (they would only be called once,> > not every time the task is 
started).> >> > What I wonder is what could we do to avoid this common 
pitfall:> > - document it somewhere (a common issues/troubleshooting section in 
the> > docs would be good to have anyways) and just accept the issue> > - 
religiously initialize globals myself before being used (a pain, error> > 
prone, and a bit adhoc, working only for FLAT mode)> > > When using globals, 
best practice is to make it really clear that the> variables are global. Many 
programmers do this by prefixing global variable> names with g_*.> > I take a 
different approach: A long time ago, I started grouping all> globals in a 
struct, which has one global instance called Global. It makes> it easy to find 
all globals, and furthermore at the start of the program as> a matter of policy 
the first thing I do is memset() the Global struct to 0.> Yes, I know that is 
often redundant to the startup code, but in some> situations the startup code 
doesn't initialize globals. The FLAT model is> one example of this (from the 
2nd invocation onwards). I've seen other> examples of this over the years. By 
memset()ing your globals at the start> of main() you can rest assured that the 
globals are in fact zeroed,> regardless of whatever else happened before 
main(). It has another side> benefit: with globals grouped this way, it becomes 
trivial to take a> standalone program and turn it into a component of a larger 
program.> tl;dr, this> approach has worked great for me for a long time.That 
sounds like a good approach.> > Caveat: It won't help if your program (or any 
API called by it) uses> globals that are outside your control, and therefore, 
not initialized by> you. :-/Yes, my concern is about functions such as 
getopt(). If you just follow thedescription of the API and use it as normal you 
reach this pitfall. I was lookingfor some approach to avoid this as much as 
possible. For getopt() I see there'seven no standard getopt_r(), so we would 
have to provide our own, which may notbe a bad idea.Still, this issue will 
probably present in many other places.> > Nathan> Best,Matias

Re: avoiding pitfal of reuse of globals in FLAT mode?

2021-03-23 Thread Matias N.


On Tue, Mar 23, 2021, at 22:09, Nathan Hartman wrote:
> On Tue, Mar 23, 2021 at 8:39 PM Matias N.  > wrote:
> 
> > Hi,
> > while using getopt() from a task started from NSH I realized subsequent
> > calls reused the global optind and similar variables resulting in different
> > results each time. I'm aware this is expected in FLAT mode and is related
> > to the issue of static C++ constructors (they would only be called once,
> > not every time the task is started).
> >
> > What I wonder is what could we do to avoid this common pitfall:
> > - document it somewhere (a common issues/troubleshooting section in the
> > docs would be good to have anyways) and just accept the issue
> > - religiously initialize globals myself before being used (a pain, error
> > prone, and a bit adhoc, working only for FLAT mode)
> 
> 
> When using globals, best practice is to make it really clear that the
> variables are global. Many programmers do this by prefixing global variable
> names with g_*.
> 
> I take a different approach: A long time ago, I started grouping all
> globals in a struct, which has one global instance called Global. It makes
> it easy to find all globals, and furthermore at the start of the program as
> a matter of policy the first thing I do is memset() the Global struct to 0.
> Yes, I know that is often redundant to the startup code, but in some
> situations the startup code doesn't initialize globals. The FLAT model is
> one example of this (from the 2nd invocation onwards). I've seen other
> examples of this over the years. By memset()ing your globals at the start
> of main() you can rest assured that the globals are in fact zeroed,
> regardless of whatever else happened before main(). It has another side
> benefit: with globals grouped this way, it becomes trivial to take a
> standalone program and turn it into a component of a larger program.
> tl;dr, this
> approach has worked great for me for a long time.

That sounds like a good approach.

> 
> Caveat: It won't help if your program (or any API called by it) uses
> globals that are outside your control, and therefore, not initialized by
> you. :-/

Yes, my concern is about functions such as getopt(). If you just follow the
description of the API and use it as normal you reach this pitfall. I was 
looking
for some approach to avoid this as much as possible. For getopt() I see there's
even no standard getopt_r(), so we would have to provide our own, which may not
be a bad idea.
Still, this issue will probably present in many other places.

> 
> Nathan
> 

Best,
Matias

Re: avoiding pitfal of reuse of globals in FLAT mode?

2021-03-23 Thread Nathan Hartman
On Tue, Mar 23, 2021 at 8:39 PM Matias N.  wrote:

> Hi,
> while using getopt() from a task started from NSH I realized subsequent
> calls reused the global optind and similar variables resulting in different
> results each time. I'm aware this is expected in FLAT mode and is related
> to the issue of static C++ constructors (they would only be called once,
> not every time the task is started).
>
> What I wonder is what could we do to avoid this common pitfall:
> - document it somewhere (a common issues/troubleshooting section in the
> docs would be good to have anyways) and just accept the issue
> - religiously initialize globals myself before being used (a pain, error
> prone, and a bit adhoc, working only for FLAT mode)


When using globals, best practice is to make it really clear that the
variables are global. Many programmers do this by prefixing global variable
names with g_*.

I take a different approach: A long time ago, I started grouping all
globals in a struct, which has one global instance called Global. It makes
it easy to find all globals, and furthermore at the start of the program as
a matter of policy the first thing I do is memset() the Global struct to 0.
Yes, I know that is often redundant to the startup code, but in some
situations the startup code doesn't initialize globals. The FLAT model is
one example of this (from the 2nd invocation onwards). I've seen other
examples of this over the years. By memset()ing your globals at the start
of main() you can rest assured that the globals are in fact zeroed,
regardless of whatever else happened before main(). It has another side
benefit: with globals grouped this way, it becomes trivial to take a
standalone program and turn it into a component of a larger program.
tl;dr, this
approach has worked great for me for a long time.

Caveat: It won't help if your program (or any API called by it) uses
globals that are outside your control, and therefore, not initialized by
you. :-/

Nathan


avoiding pitfal of reuse of globals in FLAT mode?

2021-03-23 Thread Matias N.
Hi,
while using getopt() from a task started from NSH I realized subsequent calls 
reused the global optind and similar variables resulting in different results 
each time. I'm aware this is expected in FLAT mode and is related to the issue 
of static C++ constructors (they would only be called once, not every time the 
task is started).

What I wonder is what could we do to avoid this common pitfall:
- document it somewhere (a common issues/troubleshooting section in the docs 
would be good to have anyways) and just accept the issue
- religiously initialize globals myself before being used (a pain, error prone, 
and a bit adhoc, working only for FLAT mode)
- support reentrant versions of all possible APIs and always use these in FLAT 
mode
- devise a mechanism to mimic what would be done by OS in KERNEL mode (add some 
custom handler to APIs internally using globals, such as getopt, that can be 
called either manually by user or by the OS itself when the task is started?)
- other?

Just trying to avoid stepping n-times on the same stone. I think this can also 
happen to unsuspecting users since
a lot of these POSIX interfaces kind of promote these interfaces which use 
globals internally.

Best,
Matias


Re: [OT] Rust is landing on Linux

2021-03-23 Thread nuno felicio
Not really...

The Rust thing ... is like "let's all do secure code by decree", almost
looks like a Java/C# thing...
It makes me think that making an embedded *BSD distro for embedded devices
will probably be something that can have some future

Secure code doesn't need to be done in a "secure" half-backed language,

Anyway


On Mon, Mar 22, 2021 at 8:17 PM Alan Carvalho de Assis 
wrote:

> Very interesting:
>
> https://www.phoronix.com/scan.php?page=news_item=Rust-Hits-Linux-Next
>
> "Meanwhile, at the Hall of Justice" ...
>
> We still looking for mentor and student to support Rust on NuttX:
>
> https://issues.apache.org/jira/browse/NUTTX-5
>