* [ECOS] uSTL hello world @ 2009-08-28 15:22 John Dallaway 2009-09-01 8:36 ` [ECOS] " cetoni GmbH - Uwe Kindler 0 siblings, 1 reply; 14+ messages in thread From: John Dallaway @ 2009-08-28 15:22 UTC (permalink / raw) To: Uwe Kindler; +Cc: eCos Discussion Hi Uwe There seems to be a problem with the uSTL hello world example given in the uSTL documentation. The code produces no output. However, if I add a printf() call after the cout.flush(), then I see _both_ messages. This is not a case of printf() flushing the output - I can observe the output from cout on the diagnostics channel _before_ the call to printf() is made. In fact, if I move the printf() call to the start of main(), then everything still works. eCos was configured with default template, pc_i82559 target, ustl and fileio packages added, no optimization. Debugging via RedBoot over ethernet. Does the hello world example work unmodified on your own hardware platform? John Dallaway --cut here-- #include <ustl.h> //#include <stdio.h> using namespace ustl; int main (int argc, char* argv[]) { cout << "Hello world!\n"; cout.flush(); // printf("Hello printf!\n"); return EXIT_SUCCESS; } -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 14+ messages in thread
* [ECOS] Re: uSTL hello world 2009-08-28 15:22 [ECOS] uSTL hello world John Dallaway @ 2009-09-01 8:36 ` cetoni GmbH - Uwe Kindler 2009-09-01 9:03 ` John Dallaway 2009-09-01 13:28 ` John Dallaway 0 siblings, 2 replies; 14+ messages in thread From: cetoni GmbH - Uwe Kindler @ 2009-09-01 8:36 UTC (permalink / raw) To: John Dallaway; +Cc: ecos-discuss Hi John, > There seems to be a problem with the uSTL hello world example given in > the uSTL documentation. The code produces no output. However, if I add a > printf() call after the cout.flush(), then I see _both_ messages. > > This is not a case of printf() flushing the output - I can observe the > output from cout on the diagnostics channel _before_ the call to > printf() is made. In fact, if I move the printf() call to the start of > main(), then everything still works. I can confirm this on my target. For me it smells like a linker issue. I wrote the following main function from the example an added a test function with a printf call that is not called from main. void test() { printf("Hello printf2!\n"); } int main (int argc, char* argv[]) { cout << "Hello world!\n"; cout.flush(); return EXIT_SUCCESS; } If I execute main then I can see the output of cout. If I remove the test function with the printf reference then the main function does not print anything. So adding a printf reference makes cout working - so I think this is a linker issue. The stream objects are declared in the file ofstream.cpp: #ifdef CYGVAR_USTL_CIN_COUT_CERR ifstream cin (STDIN_FILENO); ofstream cout (STDOUT_FILENO); ofstream cerr (STDERR_FILENO); #endif For the creation of these objects there is no constructor priority set - could this be the problem? Maybe the stream objects are created prior to the creation of the libc stream objects. In the uSTL code there is no explicit printf reference. It only uses vsnprintf. Uwe -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 14+ messages in thread
* [ECOS] Re: uSTL hello world 2009-09-01 8:36 ` [ECOS] " cetoni GmbH - Uwe Kindler @ 2009-09-01 9:03 ` John Dallaway 2009-09-01 12:22 ` cetoni GmbH - Uwe Kindler 2009-09-01 13:28 ` John Dallaway 1 sibling, 1 reply; 14+ messages in thread From: John Dallaway @ 2009-09-01 9:03 UTC (permalink / raw) To: Uwe Kindler; +Cc: ecos-discuss Hi Uwe Uwe Kindler wrote: > I can confirm this on my target. For me it smells like a linker issue. I agree that this smells like a linker issue. Does the problem still occur if you link without -Wl,--gc-sections ? John Dallaway -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 14+ messages in thread
* [ECOS] Re: uSTL hello world 2009-09-01 9:03 ` John Dallaway @ 2009-09-01 12:22 ` cetoni GmbH - Uwe Kindler 0 siblings, 0 replies; 14+ messages in thread From: cetoni GmbH - Uwe Kindler @ 2009-09-01 12:22 UTC (permalink / raw) To: John Dallaway; +Cc: ecos-discuss Hi John, > I agree that this smells like a linker issue. Does the problem still > occur if you link without -Wl,--gc-sections ? Yes the problem does still occur. Regards, Uwe -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 14+ messages in thread
* [ECOS] Re: uSTL hello world 2009-09-01 8:36 ` [ECOS] " cetoni GmbH - Uwe Kindler 2009-09-01 9:03 ` John Dallaway @ 2009-09-01 13:28 ` John Dallaway 2009-09-08 15:14 ` cetoni GmbH - Uwe Kindler 1 sibling, 1 reply; 14+ messages in thread From: John Dallaway @ 2009-09-01 13:28 UTC (permalink / raw) To: Uwe Kindler; +Cc: ecos-discuss Hi Uwe Uwe Kindler wrote: > The stream objects are declared in the file ofstream.cpp: > > #ifdef CYGVAR_USTL_CIN_COUT_CERR > ifstream cin (STDIN_FILENO); > ofstream cout (STDOUT_FILENO); > ofstream cerr (STDERR_FILENO); > #endif > > For the creation of these objects there is no constructor priority set - > could this be the problem? Maybe the stream objects are created prior to > the creation of the libc stream objects. In the uSTL code there is no > explicit printf reference. It only uses vsnprintf. The libc static constructors are at priority 56000+ so should be called before uSTL constructors at the default priority of 65535. So I don't think this is the problem. Nevertheless, uSTL static objects should probably be constructed with elevated priority in case they are needed within application-level static constructors. Something to think about. Back to the original problem. It may be easiest to drill down into the cout call hierarchy under debug and compare with the equivalent call stack from a working application in order to narrow the problem search space. John Dallaway -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 14+ messages in thread
* [ECOS] Re: uSTL hello world 2009-09-01 13:28 ` John Dallaway @ 2009-09-08 15:14 ` cetoni GmbH - Uwe Kindler 2009-09-08 15:59 ` John Dallaway 0 siblings, 1 reply; 14+ messages in thread From: cetoni GmbH - Uwe Kindler @ 2009-09-08 15:14 UTC (permalink / raw) To: John Dallaway; +Cc: ecos-discuss Hi John, > Back to the original problem. It may be easiest to drill down into the > cout call hierarchy under debug and compare with the equivalent call > stack from a working application in order to narrow the problem search > space. > > John Dallaway O.k. - I did this and here are my results. In both situations (reference to printf exists and no reference to printf exists in main.cpp) the call cout << "Hello world!\n" brings us into the function readwritev() in fileio/io.cxx. In this file the lines 105 - 108 makes the difference: fp = cyg_fp_get( fd ); if( fp == NULL ) FILEIO_RETURN(EBADF); If a printf call is present in main.cpp then cyg_fp_get() returns a valid file pointer. If no printf call is present in main.cpp the cyg_fp_get() returns 0 and the function returns with EBADF. Here are the local variables in readwritev() with printf: fd 0x1 _iov 0xa0140948 iov_len 0x1 direction 0x2 cnt 0xd len 0xd ret 0x11110008 _idx 0x1 fp 0xa0140d90 iov 0xa014086c uio {...} op 0xa014095c and here are the locals in readwritev() without printf in main: fd 0x1 _iov 0xa013d5e8 iov_len 0x1 direction 0x2 cnt 0x11110006 len 0xd ret 0x11110008 _idx 0x1 fp 0x00000000 iov 0xa013d50c uio {...} op 0xa013d5fc Any idea what is going wrong here before I dig even more deeper? Regards, Uwe -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 14+ messages in thread
* [ECOS] Re: uSTL hello world 2009-09-08 15:14 ` cetoni GmbH - Uwe Kindler @ 2009-09-08 15:59 ` John Dallaway 2009-09-09 7:00 ` cetoni GmbH - Uwe Kindler 0 siblings, 1 reply; 14+ messages in thread From: John Dallaway @ 2009-09-08 15:59 UTC (permalink / raw) To: Uwe Kindler; +Cc: ecos-discuss Hi Uwe Uwe Kindler wrote: > >> Back to the original problem. It may be easiest to drill down into the >> cout call hierarchy under debug and compare with the equivalent call >> stack from a working application in order to narrow the problem search >> space. >> >> John Dallaway > > O.k. - I did this and here are my results. > > In both situations (reference to printf exists and no reference to > printf exists in main.cpp) the call cout << "Hello world!\n" brings us > into the function readwritev() in fileio/io.cxx. In this file the lines > 105 - 108 makes the difference: > > fp = cyg_fp_get( fd ); > > if( fp == NULL ) > FILEIO_RETURN(EBADF); > > If a printf call is present in main.cpp then cyg_fp_get() returns a > valid file pointer. If no printf call is present in main.cpp the > cyg_fp_get() returns 0 and the function returns with EBADF. > > Here are the local variables in readwritev() with printf: > > fd 0x1 > _iov 0xa0140948 > iov_len 0x1 > direction 0x2 > cnt 0xd > len 0xd > ret 0x11110008 > _idx 0x1 > fp 0xa0140d90 > iov 0xa014086c > uio {...} > op 0xa014095c > > and here are the locals in readwritev() without printf in main: > > fd 0x1 > _iov 0xa013d5e8 > iov_len 0x1 > direction 0x2 > cnt 0x11110006 > len 0xd > ret 0x11110008 > _idx 0x1 > fp 0x00000000 > iov 0xa013d50c > uio {...} > op 0xa013d5fc > > Any idea what is going wrong here before I dig even more deeper? The file descriptor (fd) is unchanged between working and non-working code which suggests that the relevant descriptor table entry is not being initialised. Try planting breakpoints at cyg_fd_assign() and cyg_fd_alloc(). I expect these will be called in the case where cout is working and the call stack may provide a clue as to what is triggering the correct behaviour. John Dallaway -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 14+ messages in thread
* [ECOS] Re: uSTL hello world 2009-09-08 15:59 ` John Dallaway @ 2009-09-09 7:00 ` cetoni GmbH - Uwe Kindler 2009-09-09 11:55 ` John Dallaway 0 siblings, 1 reply; 14+ messages in thread From: cetoni GmbH - Uwe Kindler @ 2009-09-09 7:00 UTC (permalink / raw) To: John Dallaway; +Cc: ecos-discuss Hi John, > The file descriptor (fd) is unchanged between working and non-working > code which suggests that the relevant descriptor table entry is not > being initialised. Try planting breakpoints at cyg_fd_assign() and > cyg_fd_alloc(). I expect these will be called in the case where cout is > working and the call stack may provide a clue as to what is triggering > the correct behaviour. O.k. I followed your suggestions and that are my results. If printf exists in main.cpp then both functions cyg_fd_assign() and cyg_fd_alloc() will get called for stdin and stdout. At the end of this message there is the call stack for stdin. If printf is not present in main, then both functions will not get called for stdin and stdout and I think I now know why. In the ustl package in ofstream.cpp the streams are not created because the streams (cout, cin, cerr) are declared this way: ifstream cin (STDIN_FILENO); ofstream cout (STDOUT_FILENO); ofstream cerr (STDERR_FILENO); That means they use the fileno to open the streams - they do not create them. But the streams are not present, because no function uses stdout, stdin, that means there are no references and the linker throws stdout and stdin away. This is the reason why the static constructors of stdout and stdin are never get called. Here is my proposal to solve this problem. I changed the declaration of cout, cin and cerr this way: ifstream cin (((Cyg_StdioStream *)stdin)->get_dev()); ofstream cout (((Cyg_StdioStream *)stdout)->get_dev()); ofstream cerr (((Cyg_StdioStream *)stderr)->get_dev()); This ensures that stdout, stdin and stderr are created. After this change cyg_fd_assign() and cyg_fd_alloc() will get called if there is no printf function in main.cpp. The call cout << "Hello world!\n" works now. I noticed that the message is already printed before cout.flush() is called. So it seems cout.flush() is not required if a proper serial driver is used. If I use the diagnostic serial driver, then I always needed to call cout.flush(). If you agree to my proposal then I will provide a patch. Regards, Uwe Thread [1] (Suspended: Breakpoint hit.) 7 cyg_fd_alloc() opt\ecos\ecos\packages\io\fileio\current\src\fd.cxx:230 0xa011d3a8 6 open() \opt\ecos\ecos\packages\io\fileio\current\src\file.cxx:205 0xa011f448 5 cyg_stdio_open() \home\Nutzer\final_ustl_0D_install\include\cyg\libc\stdio\io.inl:101 0xa0130228 4 Cyg_libc_stdio_find_filename() \opt\ecos\ecos\packages\language\c\libc\stdio\current\src\common\stdiosupp.cxx:76 0xa01302c0 3 __static_initialization_and_destruction_0() \opt\ecos\ecos\packages\language\c\libc\stdio\current\src\common\stdin.cxx:86 0xa013000c 2 _GLOBAL__I.56000_cyg_libc_stdio_stdin() \opt\ecos\ecos\packages\language\c\libc\stdio\current\src\common\stdin.cxx:107 0xa01300c4 1 cyg_hal_invoke_constructors() \opt\ecos\ecos\packages\hal\arm\arch\current\src\hal_misc.c:213 0xa0104458 -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 14+ messages in thread
* [ECOS] Re: uSTL hello world 2009-09-09 7:00 ` cetoni GmbH - Uwe Kindler @ 2009-09-09 11:55 ` John Dallaway 2009-09-10 0:32 ` Jonathan Larmour 0 siblings, 1 reply; 14+ messages in thread From: John Dallaway @ 2009-09-09 11:55 UTC (permalink / raw) To: Uwe Kindler, Jonathan Larmour; +Cc: ecos-discuss Hi Uwe and Jifl Uwe Kindler wrote: > If printf is not present in main, then both functions will not get > called for stdin and stdout and I think I now know why. In the ustl > package in ofstream.cpp the streams are not created because the streams > (cout, cin, cerr) are declared this way: > > ifstream cin (STDIN_FILENO); > ofstream cout (STDOUT_FILENO); > ofstream cerr (STDERR_FILENO); > > That means they use the fileno to open the streams - they do not create > them. But the streams are not present, because no function uses stdout, > stdin, that means there are no references and the linker throws stdout > and stdin away. This is the reason why the static constructors of stdout > and stdin are never get called. > > Here is my proposal to solve this problem. I changed the declaration of > cout, cin and cerr this way: > > ifstream cin (((Cyg_StdioStream *)stdin)->get_dev()); > ofstream cout (((Cyg_StdioStream *)stdout)->get_dev()); > ofstream cerr (((Cyg_StdioStream *)stderr)->get_dev()); > > This ensures that stdout, stdin and stderr are created. After this > change cyg_fd_assign() and cyg_fd_alloc() will get called if there is no > printf function in main.cpp. The call cout << "Hello world!\n" works > now. I noticed that the message is already printed before cout.flush() > is called. So it seems cout.flush() is not required if a proper serial > driver is used. If I use the diagnostic serial driver, then I always > needed to call cout.flush(). > > If you agree to my proposal then I will provide a patch. Uwe, congratulations on tracking this down. Your analysis makes good sense. Jifl, is there a preferred way to ensure initialisation of the stdio streams in the file descriptor table? I note that open() in the file I/O package uses: CYG_REFERENCE_OBJECT(stdin); CYG_REFERENCE_OBJECT(stdout); CYG_REFERENCE_OBJECT(stderr); Is this addressing the same issue that we're observing with uSTL? John Dallaway -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 14+ messages in thread
* [ECOS] Re: uSTL hello world 2009-09-09 11:55 ` John Dallaway @ 2009-09-10 0:32 ` Jonathan Larmour 2009-09-11 19:25 ` Bart Veer 0 siblings, 1 reply; 14+ messages in thread From: Jonathan Larmour @ 2009-09-10 0:32 UTC (permalink / raw) To: John Dallaway; +Cc: Uwe Kindler, ecos-discuss, Nick Garnett [ NB Nick, see below... ] John Dallaway wrote: > Uwe Kindler wrote: >>If printf is not present in main, then both functions will not get >>called for stdin and stdout and I think I now know why. In the ustl >>package in ofstream.cpp the streams are not created because the streams >>(cout, cin, cerr) are declared this way: >> >>ifstream cin (STDIN_FILENO); >>ofstream cout (STDOUT_FILENO); >>ofstream cerr (STDERR_FILENO); >> >>That means they use the fileno to open the streams - they do not create >>them. But the streams are not present, because no function uses stdout, >>stdin, that means there are no references and the linker throws stdout >>and stdin away. This is the reason why the static constructors of stdout >>and stdin are never get called. >> >>Here is my proposal to solve this problem. I changed the declaration of >>cout, cin and cerr this way: >> >>ifstream cin (((Cyg_StdioStream *)stdin)->get_dev()); >>ofstream cout (((Cyg_StdioStream *)stdout)->get_dev()); >>ofstream cerr (((Cyg_StdioStream *)stderr)->get_dev()); >> >>This ensures that stdout, stdin and stderr are created. After this >>change cyg_fd_assign() and cyg_fd_alloc() will get called if there is no >>printf function in main.cpp. The call cout << "Hello world!\n" works >>now. I noticed that the message is already printed before cout.flush() >>is called. So it seems cout.flush() is not required if a proper serial >>driver is used. If I use the diagnostic serial driver, then I always >>needed to call cout.flush(). >> >>If you agree to my proposal then I will provide a patch. > > > Uwe, congratulations on tracking this down. Your analysis makes good sense. > > Jifl, is there a preferred way to ensure initialisation of the stdio > streams in the file descriptor table? I note that open() in the file I/O > package uses: > > CYG_REFERENCE_OBJECT(stdin); > CYG_REFERENCE_OBJECT(stdout); > CYG_REFERENCE_OBJECT(stderr); > > Is this addressing the same issue that we're observing with uSTL? I think there's a more fundamental problem, not specific to uSTL (so I think Uwe's workaround isn't really appropriate). That is that something like: write(STDOUT_FILENO, buf, n); can't be guaranteed to just work, at present. That's a bug. I think those CYG_REFERENCE_OBJECT lines (and surrounding ifdef) need to move out of open() and into cyg_fd_init(). Theoretically cyg_fp_get() would be slightly better, but that is called a lot, and there is a trivial but non-zero overhead to CYG_REFERENCE_OBJECT. I'd appreciate Nick's opinion on this proposal if possible though. It does mean that including the fileio package at all in a configuration would then guarantee pulling in stdin/stdout/stderr, even irrespective of use. Maybe the number of people this would affect is too small to care about. Maybe there should be a default-enabled option, to allow it to be turned off to remove that dependency. Taking the usual principle of "leave it to the user", I think I'd personally lean towards the latter. Jifl -- --["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [ECOS] Re: uSTL hello world 2009-09-10 0:32 ` Jonathan Larmour @ 2009-09-11 19:25 ` Bart Veer 2009-09-12 2:49 ` Jonathan Larmour 0 siblings, 1 reply; 14+ messages in thread From: Bart Veer @ 2009-09-11 19:25 UTC (permalink / raw) To: Jonathan Larmour; +Cc: ecos-discuss >>>>> "Jifl" == Jonathan Larmour <jifl@jifvik.org> writes: <snip> >> Jifl, is there a preferred way to ensure initialisation of the >> stdio streams in the file descriptor table? I note that open() >> in the file I/O package uses: >> >> CYG_REFERENCE_OBJECT(stdin); >> CYG_REFERENCE_OBJECT(stdout); >> CYG_REFERENCE_OBJECT(stderr); >> >> Is this addressing the same issue that we're observing with >> uSTL? Jifl> I think there's a more fundamental problem, not specific to Jifl> uSTL (so I think Uwe's workaround isn't really appropriate). Jifl> That is that something like: Jifl> write(STDOUT_FILENO, buf, n); Jifl> can't be guaranteed to just work, at present. That's a bug. Jifl> I think those CYG_REFERENCE_OBJECT lines (and surrounding Jifl> ifdef) need to move out of open() and into cyg_fd_init(). Jifl> Theoretically cyg_fp_get() would be slightly better, but Jifl> that is called a lot, and there is a trivial but non-zero Jifl> overhead to CYG_REFERENCE_OBJECT. I'd appreciate Nick's Jifl> opinion on this proposal if possible though. It does mean Jifl> that including the fileio package at all in a configuration Jifl> would then guarantee pulling in stdin/stdout/stderr, even Jifl> irrespective of use. Maybe the number of people this would Jifl> affect is too small to care about. Maybe there should be a Jifl> default-enabled option, to allow it to be turned off to Jifl> remove that dependency. Jifl> Taking the usual principle of "leave it to the user", I Jifl> think I'd personally lean towards the latter. I think there is another approach which might fit in better with linker garbage collection. Instead of #define'ing STDOUT_FILENO as 1, declare it as an extern const char. Then provide the variable STDOUT_FILENO in some module which causes the necessary initialization to happen. It is slightly more expensive: a bit of space for the const variable, an extra memory access for the write() call. However it would eliminate the need for CYG_REFERENCE_OBJECT's and it would allow linker garbage collection to work as normal. Obviously code which uses write(1, buf, n) would still be broken, and http://www.opengroup.org/onlinepubs/009695399/basedefs/unistd.h.html requires that STDOUT_FILENO be defined as 1. Hence my proposal would not be fully standards-compliant. Bart -- Bart Veer eCos Configuration Architect eCosCentric Limited The eCos experts http://www.ecoscentric.com/ Barnwell House, Barnwell Drive, Cambridge, UK. Tel: +44 1223 245571 Registered in England and Wales: Reg No 4422071. >>>> Visit us at ESC-Boston http://www.embedded.com/esc/boston <<<< >>>> Sep 22-23 on Stand 226 at Hynes Convention Center, Boston <<<< -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [ECOS] Re: uSTL hello world 2009-09-11 19:25 ` Bart Veer @ 2009-09-12 2:49 ` Jonathan Larmour 2009-09-29 14:28 ` Bart Veer 0 siblings, 1 reply; 14+ messages in thread From: Jonathan Larmour @ 2009-09-12 2:49 UTC (permalink / raw) To: Bart Veer; +Cc: ecos-discuss Bart Veer wrote: >>>>>>"Jifl" == Jonathan Larmour <jifl@jifvik.org> writes: > > > <snip> > > >> Jifl, is there a preferred way to ensure initialisation of the > >> stdio streams in the file descriptor table? I note that open() > >> in the file I/O package uses: > >> > >> CYG_REFERENCE_OBJECT(stdin); > >> CYG_REFERENCE_OBJECT(stdout); > >> CYG_REFERENCE_OBJECT(stderr); > >> > >> Is this addressing the same issue that we're observing with > >> uSTL? > > Jifl> I think there's a more fundamental problem, not specific to > Jifl> uSTL (so I think Uwe's workaround isn't really appropriate). > Jifl> That is that something like: > > Jifl> write(STDOUT_FILENO, buf, n); > > Jifl> can't be guaranteed to just work, at present. That's a bug. > > Jifl> I think those CYG_REFERENCE_OBJECT lines (and surrounding > Jifl> ifdef) need to move out of open() and into cyg_fd_init(). > Jifl> Theoretically cyg_fp_get() would be slightly better, but > Jifl> that is called a lot, and there is a trivial but non-zero > Jifl> overhead to CYG_REFERENCE_OBJECT. I'd appreciate Nick's > Jifl> opinion on this proposal if possible though. It does mean > Jifl> that including the fileio package at all in a configuration > Jifl> would then guarantee pulling in stdin/stdout/stderr, even > Jifl> irrespective of use. Maybe the number of people this would > Jifl> affect is too small to care about. Maybe there should be a > Jifl> default-enabled option, to allow it to be turned off to > Jifl> remove that dependency. > > Jifl> Taking the usual principle of "leave it to the user", I > Jifl> think I'd personally lean towards the latter. > > I think there is another approach which might fit in better with > linker garbage collection. Instead of #define'ing STDOUT_FILENO as 1, > declare it as an extern const char. Then provide the variable > STDOUT_FILENO in some module which causes the necessary initialization > to happen. It is slightly more expensive: a bit of space for the const > variable, an extra memory access for the write() call. However it > would eliminate the need for CYG_REFERENCE_OBJECT's and it would allow > linker garbage collection to work as normal. > > Obviously code which uses write(1, buf, n) would still be broken, and > http://www.opengroup.org/onlinepubs/009695399/basedefs/unistd.h.html > requires that STDOUT_FILENO be defined as 1. Hence my proposal would > not be fully standards-compliant. While that's an interesting workaround, I think your last paragraph is the killer, chiefly because I think write(1, buf, n) should still be able to work. *However*, maybe the config option could instead be between standards compliant mode, and "not quite right, but may often still work" mode. Unfortunately we have another problem. I've looked at the output of our recent compilers, and I see that CYG_REFERENCE_OBJECT no longer appears to be effective :-(. The reference gets removed by more aggressive compiler optimisation at -O2. This is a much wider problem than just stdin/out/err of course. Solving that efficiently may be difficult (although I don't consider the current implementation to necessarily be efficient either, when it worked, anyway). Managing to get the reference into .text/.rodata would probably be better than .data/.bss. Even better would be if it were possible to play tricks to get it into a non-loadable section, although that starts to venture into the world of HAL-specific stuff. I see a .comment section though. Something along those lines might work (and by overridable by specific HALs if needed). But I've experimented (admittedly briefly) and not got as far as even making the reference. I've tried using various attributes, nested functions, volatiles, embedding asm(".word " #__object__ ";"), etc. It may be that we can only do this properly using HAL-specific inline asm :-(. The least worst idea I've had which actually creates a reference is to have a real function cyg_reference_object(void*) and call it with the address of the object to reference, but which returns immediately. Any other ideas? At least there are not many uses of CYG_REFERENCE_OBJECT. Jifl -- --["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [ECOS] Re: uSTL hello world 2009-09-12 2:49 ` Jonathan Larmour @ 2009-09-29 14:28 ` Bart Veer 2009-09-29 15:36 ` Jonathan Larmour 0 siblings, 1 reply; 14+ messages in thread From: Bart Veer @ 2009-09-29 14:28 UTC (permalink / raw) To: Jonathan Larmour; +Cc: ecos-discuss >>>>> "Jifl" == Jonathan Larmour <jifl@jifvik.org> writes: <snip> Jifl> Unfortunately we have another problem. I've looked at the Jifl> output of our recent compilers, and I see that Jifl> CYG_REFERENCE_OBJECT no longer appears to be effective :-(. Jifl> The reference gets removed by more aggressive compiler Jifl> optimisation at -O2. This is a much wider problem than just Jifl> stdin/out/err of course. Jifl> Solving that efficiently may be difficult (although I don't Jifl> consider the current implementation to necessarily be Jifl> efficient either, when it worked, anyway). Managing to get Jifl> the reference into .text/.rodata would probably be better Jifl> than .data/.bss. Even better would be if it were possible to Jifl> play tricks to get it into a non-loadable section, although Jifl> that starts to venture into the world of HAL-specific stuff. Jifl> I see a .comment section though. Something along those lines Jifl> might work (and by overridable by specific HALs if needed). Jifl> But I've experimented (admittedly briefly) and not got as Jifl> far as even making the reference. I've tried using various Jifl> attributes, nested functions, volatiles, embedding Jifl> asm(".word " #__object__ ";"), etc. It may be that we can Jifl> only do this properly using HAL-specific inline asm :-(. The Jifl> least worst idea I've had which actually creates a reference Jifl> is to have a real function cyg_reference_object(void*) and Jifl> call it with the address of the object to reference, but Jifl> which returns immediately. Jifl> Any other ideas? At least there are not many uses of Jifl> CYG_REFERENCE_OBJECT. I think the following may do the trick: ---------------------------------------------------------------------------- // The unused attribute stops the compiler warning about the variable // not being used. // The used attribute prevents the compiler from optimizing it away. #define NEW_CYG_REFERENCE_OBJECT(__object__) \ CYG_MACRO_START \ static const void* __cygvar_discard_me__ \ __attribute__ ((unused, used)) = (const void*)&(__object__); \ CYG_MACRO_END ---------------------------------------------------------------------------- I have tried it in a simple testcase at -O2. The compiler does not optimize away __cygvar_discard_me__ because the used attribute prevents that. Hence the referenced object gets pulled in during the link. Subsequently linker garbage collection eliminates __cygvar_discard_me__. If the referenced object is a C++ object then it will be preserved because of the KEEP(*.ctors) in the linker script. So, even though it seems peculiar to have a variable both used and unused, that combo appears to do what we want and should be fully portable. Looking at the gcc ChangeLog-2001, attribute(used) was added on 2001-10-18 so has probably been available since gcc 3.1 days. However there is a comment in cyg_type.h associated with CYGBLD_ATTRIB_USED claiming >= 3.3.2. Let me know if it still does not solve the problem in al cases, and I can investigate further. Bart -- Bart Veer eCos Configuration Architect eCosCentric Limited The eCos experts http://www.ecoscentric.com/ Barnwell House, Barnwell Drive, Cambridge, UK. Tel: +44 1223 245571 Registered in England and Wales: Reg No 4422071. >>>> Visit us at ESC-UK http://www.embedded.co.uk <<<< >>>> Oct 7-8 on Stand 433 at FIVE ISC, Farnborough <<<< -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [ECOS] Re: uSTL hello world 2009-09-29 14:28 ` Bart Veer @ 2009-09-29 15:36 ` Jonathan Larmour 0 siblings, 0 replies; 14+ messages in thread From: Jonathan Larmour @ 2009-09-29 15:36 UTC (permalink / raw) To: Bart Veer; +Cc: ecos-discuss, Uwe Kindler Bart Veer wrote: >>>>>>"Jifl" == Jonathan Larmour <jifl@jifvik.org> writes: > > > <snip> > > Jifl> Unfortunately we have another problem. I've looked at the > Jifl> output of our recent compilers, and I see that > Jifl> CYG_REFERENCE_OBJECT no longer appears to be effective :-(. [snip failed attempts to resolve] > Jifl> Any other ideas? At least there are not many uses of > Jifl> CYG_REFERENCE_OBJECT. > > I think the following may do the trick: > > ---------------------------------------------------------------------------- > // The unused attribute stops the compiler warning about the variable > // not being used. > // The used attribute prevents the compiler from optimizing it away. > > #define NEW_CYG_REFERENCE_OBJECT(__object__) \ > CYG_MACRO_START \ > static const void* __cygvar_discard_me__ \ > __attribute__ ((unused, used)) = (const void*)&(__object__); \ > CYG_MACRO_END > ---------------------------------------------------------------------------- > > I have tried it in a simple testcase at -O2. The compiler does not > optimize away __cygvar_discard_me__ because the used attribute > prevents that. Hence the referenced object gets pulled in during the > link. Subsequently linker garbage collection eliminates > __cygvar_discard_me__. If the referenced object is a C++ object then > it will be preserved because of the KEEP(*.ctors) in the linker > script. So, even though it seems peculiar to have a variable both used > and unused, that combo appears to do what we want and should be fully > portable. That does seem very peculiar, but if it works.... > Looking at the gcc ChangeLog-2001, attribute(used) was added on > 2001-10-18 so has probably been available since gcc 3.1 days. However > there is a comment in cyg_type.h associated with CYGBLD_ATTRIB_USED > claiming >= 3.3.2. ISTR something about the behaviour of that attribute changing at some point- perhaps it was buggy before. We could ifdef CYG_REFERENCE_OBJECT based on GCC version easily enough. > Let me know if it still does not solve the problem in al cases, and I > can investigate further. Now I think it's back to Uwe to verify that this, in combination with the stuff I mentioned before, does resolve his uSTL problems. Uwe? Even better if you can submit an associated patch. Jifl -- --["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2009-09-29 15:36 UTC | newest] Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2009-08-28 15:22 [ECOS] uSTL hello world John Dallaway 2009-09-01 8:36 ` [ECOS] " cetoni GmbH - Uwe Kindler 2009-09-01 9:03 ` John Dallaway 2009-09-01 12:22 ` cetoni GmbH - Uwe Kindler 2009-09-01 13:28 ` John Dallaway 2009-09-08 15:14 ` cetoni GmbH - Uwe Kindler 2009-09-08 15:59 ` John Dallaway 2009-09-09 7:00 ` cetoni GmbH - Uwe Kindler 2009-09-09 11:55 ` John Dallaway 2009-09-10 0:32 ` Jonathan Larmour 2009-09-11 19:25 ` Bart Veer 2009-09-12 2:49 ` Jonathan Larmour 2009-09-29 14:28 ` Bart Veer 2009-09-29 15:36 ` Jonathan Larmour
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).