Jump to content

application hangs when setting label text


crteensy

Recommended Posts

My app repeatedly calls this function:

void run()
{
// handle baking state
switch(_state)
{
case EPassive:
break;
case EBaking:
break;
}
// get events
GEvent* pe = geventEventWait(&_gl, 0);
if (pe != NULL)
{
switch(pe->type) {
case GEVENT_GWIN_BUTTON:
if (((GEventGWinButton*)pe)->gwin == _ghBtnBack) {
leave();
}
else if (((GEventGWinButton*)pe)->gwin == _ghBtnStartStop) {
startOrStop();
}
break;
case GEVENT_GWIN_SLIDER:
if (((GEventGWinSlider*)pe)->gwin == _ghHeatUpDial) {
updateHeatUpLabel();
}
}
}
gfxYield();
}

When updateHeatUpLabel() is called, a text is updated. I do this in two ways which show different behavior. The first (as shown here, drawing text manually), does not result in a hang:

void updateHeatUpLabel()
{
static char buf[7];
GHeatUp_dTdt_DialObject* p = (GHeatUp_dTdt_DialObject*)_ghHeatUpDial;
if (p->unit == EdTdt_KperHour)
{
snprintf(buf, 7, "%2u K/h", (unsigned int)p->value);
}
else
{
snprintf(buf, 7, "%2u K/m", (unsigned int)p->value);
}
buf[6] = 0;
gdispFillString(100, 20, buf, p->w.g.font, p->w.pstyle->enabled.text, p->w.pstyle->background);
// gwinSetText(_ghHeatUpLabel, buf, FALSE);
}

When I swap in the call to gwinSetText() call, I get a hang. My debugger shows this call stack:

#0 0xb7fdd424	__kernel_vsyscall () (??:??)
#1 0xb7c29a1c sched_yield() (../sysdeps/unix/syscall-template.S:81)
#2 0x80511fb gfxYield() (/ugfx/src/gos/gos_linux.c:47)
#3 ?? 0x08049d19 in BakeMode::run (this=0x8063208 ) (/mode/bakeMode.h:155)
#4 0x80497b8 Mode::runCurrent() (/mode/abstractMode.h:19)
#5 0x80496d2 loop() (/main.cpp:19)
#6 0x8049709 main(argc=1, argv=0xbffff5a4) (/main.cpp:27)

I'm compiling with gcc -O0.

Edit: This doesn't happen as soon as the label is updated, but after a seemingly random number of label updates.

Link to comment
Share on other sites

I'm not editing this into the original post because it's kind of a new facette to the problem: The application doesn't hang when I use a different font. I had UI2 Narrow, but the hang does not happen with fixed 10x20. Instead, buttons simply don't display any text.

Link to comment
Share on other sites

The problem I think is with the last parameter to gwinSetText. This last parameter tells the function whether to copy the string because it is not a static string. As your buffer is allocated on the stack you should be using TRUE for that parameter.

You might also want to look at using the snprintg function provided by ugfx. Using it instead of snprintf should compile a lot smaller as the whole stdio package from your standard library doesn't need to be included. Stdio is usually quite big.

Link to comment
Share on other sites

The buffer is not on the stack, but allocated statically. Regardless of that, I can pass whatever I want to gwinSetText - it hangs.

I also have not yet understood what I can do to avoid dynamic allocation of character arrays. When I set the text in an init struct, it will be copied into a dynamically allocated character array so the whole point of gwinSetText having a parameter to select between static and dynamic memory seems moot.

Link to comment
Share on other sites

Sorry i missed the static on the variable definition. I however just noticed you are compiling under linux. Are you compiling using the thread safe c runtime library?

I think the compile flag is gcc -pthread but please check the doco first. This flag needs to be specified as well as including the pthread library. Alternatively try compiling with our make system which (should) get it right.

Link to comment
Share on other sites

I recompiled everything with -pthread, my libc is thread-safe.

These are the compiler flags from my build log:

g++ -O0 -Wall -fexceptions -pthread -g -Iugfx -Iugfx/src/gdisp/mcufont -Iugfx/drivers/multiple/X_480x272 -Iugfx_user -I.

(yes, there are C++ flags in there. g++ ignores them for C files)

Here is the output from gcc -v:

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/4.8/lto-wrapper
Target: i686-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.2-19ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-i386/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-i386 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-i386 --with-arch-directory=i386 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-targets=all --enable-multiarch --disable-werror --with-arch-32=i686 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu
Thread model: posix

Still hangs after a seemingly random number of updates. Might this be related to button labels not being shown when I pick a different font?

This is frustrating, really. Why do I need that multithreading again? It comes with so many problems that I'm really considering writing my own widgets, because widgets are what forced me to activate ugfx's multithreading in the first place. Code size skyrocketed, I need an extra heap for ugfx on my target hardware, things crash when running on linux.

Link to comment
Share on other sites

If nothing is being shown with a particular font then this is an ideal place to start debugging.

The primary advantage of prototyping using a desktop operating system like linux or windows is that you can use the ide debugger and thus more easily debug your application.

With regard to multi threading, this is required by any windowing system except the most rudimentary simply by the nature of what you are doing. As mentioned before it is the input system that requires the multi-threading not so much the drawing.

Whilst I have ideas to remove that requirement it is not an easy task.

Linux and win32 emulations have been well tested, win32 probably more than linux. I would be surprised if there was a significant issue in that area simply as for the reasons above it is these two platforms that most of the gwin system was written on. That is why I was looking at possible compiler flag issues as we don't seem to be seeing the same problem.

Can you please write a test demo (something like one of the demos in ugfx) that demonstrates the problem - the simpler the better. We can then compile the same program and see if we get the same result. If we do we have something to debug, if not then we know it is something about your build environment.

Link to comment
Share on other sites

My previous example crashed with a segfault, I could now resolve that by *not* passing NULL to the label's init routine. Initializing a label apparently requires an initial non-null pointer (so I can't get around dynamic memory allocation). The attached example now hangs as described.

Old reply:

Here's a test project using your build system, stripped down to a custom widget and a label. It compiles fine but crashes with a segfault. ugfx is expected in ../ugfx just like in the build example in the wiki.

gcc barfs at a forward declaration in gwinContainer.h (I think) so I commented that out. Nothing happens between the forward declaration and the following actual typedef so that's safe.

I couldn't reply earlier because replying from within my university's network didn't work.

heatUp_dTdt_dial_simple.zip

Edited by Guest
Link to comment
Share on other sites

Some more findings for the example attached to this reply:

  • the label's text is not updated until the second call to updateHeatUpLabel(), which calls gwinSetText(). The first call does not have any apparent effect.
  • funny behavior with different fonts is still there. UI2 narrow seems to cause a hang after a while, fixed 10x20 is not displayed on the button and hangs as well

I should probably describe what to do with that round widget:

Click the small dark gray filled circle (the grip) and drag it around in the round widget centered on the screen. It will travel in the inner or the outer pair of circles. The label will be updated with a value depending on the grip's angle and a unit depending on the grip's traveling radius around the central widget. After some movement, the application hangs.

heatUp_dTdt_dial_wButton.zip

Link to comment
Share on other sites

I have had my first look at it.

Please change your OPT_CPU to x32 rather than x64. x64 has not been tested for reliability and really is not needed for an embedded system emulator. There is a very good chance there are some 64 bit problems in the library. Both x32 and x64 should run on a 64 bit Linux machine.

If your compiler complains about compiling x32 on your 64 bit machine it might be because you have not installed the 32 bit libraries for your C compiler. Each Linux distribution has a different process for doing this, some include the libraries out of the box. If you have trouble with this let us know what distribution you are running and we will see if we can google the proper install command line.

I have not tried a compile yet - that is just what struck me when I looked at it first.

Link to comment
Share on other sites

I have found the problem...

I used the dial demo you attached to debug however I am sure that the problem is likely to be the same in the button demo.

First the workaround...


wi.g.width = 40; // Used to be wi.g.width = 0;
wi.g.height = 20; // Used to be wi.g.height = 0;
ghLabel = gwinLabelCreate(0, &wi);

The widget has this nice little feature whereby it can auto-size based on the text that is in the widget. It is the only widget that supports this functionality and was at the time just an after-thought.

This functionality is perfect for a static label but when the text changes at run-time it tries to resize the widget during the label's redraw function.

Unfortunately due to changes in the redraw handler since this widget was originally written, this causes the widget to recursively redraw in certain conditions thus causing the hang leading to stack depletion some time later with its associated kernel inspired crash.

This is likely to be tricky to fix so the work-around currently is to use a fixed size label as seen above.

I will look at this in much more detail when I get some more time. Unfortunately you can tell by my slowness in getting to this that real work has been keeping me very busy. For now it will be considered a known bug.

Link to comment
Share on other sites

Yup, doesn't hang any more in both 32- and 64-bit build. Thank you!

Regarding fonts: I tried using a user-supplied font I converted with your online font converter, and it does show up on the button just like UI2 narrow. The fixed-width fonts (5x8, 7x14, 10x20) still don't show up on the button. This is fine for me now, but you should probably have a look for potential problems with the fixed-width fonts.

Link to comment
Share on other sites

I have found a reasonably simple workaround for the problem so dynamic sizing should work again with the latest master repository.

The caveat is that a dynamically sized label will only increase in size, never decrease at least until I can spend the time to fix it properly.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...