Results 1 to 24 of 24

Thread: dfGUI v3.2.1 for Linux available! (for the new DF client)

  1. #1
    Senior Member
    Join Date
    Mar 2002
    Location
    MI, U.S.
    Posts
    697

    dfGUI v3.2.1 for Linux available! (for the new DF client)

    I've changed the way the Points tab calculates its stuff. It now works correctly with the 100-structure generations.

    I've also added the feature where it monitors the last bunch of lines (currently 30) in your error.log on another tab, so we'll see how well that works.

    The titlebar text also supports substitutions similar to printf(). (Good idea Dyyryath! ) See the README file for what you can substitute. This ought to help cross-network monitoring quite a bit, assuming you have the X libraries (and the Gtk2 ones) on the remote machine. Basically you ssh into that machine, start up dfGUI there with the display set to your local box, and shade the window. Use the titlebar to do monitoring.

    The new version is available at the usual location:

    http://kadzban.is-a-geek.net/dfGUI-linux/
    "If you fail to adjust your notion of fairness to the reality of the Universe, you will probably not be happy."

    -- Originally posted by Paratima

  2. #2
    Junior Member aptarasc's Avatar
    Join Date
    May 2003
    Location
    Folsom, CA
    Posts
    18
    Bryan,
    I hope you will continue working on this port. I find this prog very useful on my Win systems.

    Something I noticed, the 3rd laxness percentage gets out of bounds, it keeps growing, and gives assertions before SegFaulting:

    (dfGUI-3.2.1-precompiled.bin:2531): Gtk-CRITICAL **: file gtkprogress.c: line 557 (gtk_progress_set_percentage): assertion `percentage >= 0 && percentage <= 1.0' failed

  3. #3
    Senior Member
    Join Date
    Mar 2002
    Location
    MI, U.S.
    Posts
    697
    It segfaults after that? Hmm... Thanks, I'll take a look at it.

    The maxima that I've set up for the laxness values are fairly arbitrary -- I think they correspond to values that Howard gave to Jeff when the laxness tracking first got put in. It's definitely a problem if something goes wrong when a value goes above the "maximum".

    Edit: I can't seem to find anything wrong with it. Of course, that doesn't mean that nothing is wrong. For example, I can't even reproduce the Gtk-CRITICAL assertion failure that you're getting. Since I'm using the same precompiled executable that you are, I have to conclude that not all versions of Gtk2 cause assertion failures when the progress bar's value gets set to something bigger than 1.0. What version of Gtk2 do you have installed? I've got 2.2.1 here.

    If I gave you a debug version, would you mind running it under gdb and getting a stack backtrace when the segfault happens?
    Last edited by bwkaz; 12-27-2003 at 10:22 PM.
    "If you fail to adjust your notion of fairness to the reality of the Universe, you will probably not be happy."

    -- Originally posted by Paratima

  4. #4
    Junior Member aptarasc's Avatar
    Join Date
    May 2003
    Location
    Folsom, CA
    Posts
    18
    I appear to be running the same version of GTK+ (2.2.1). I started a new run, so there would be no laxness, and it seg faults when it refreshes (or I hit refresh). I tried your 3.2 version and it does not fault but still has the bounds issue.

  5. #5
    Senior Member
    Join Date
    Mar 2002
    Location
    MI, U.S.
    Posts
    697
    Hmm. Well, try this debug version (should be attached). gunzip it first. I don't know if you've used gdb before, so I'll go through how to get a stack backtrace:

    Run gdb /path/to/this/dfGUI-3.2.1-precompiled

    Type run to start it up.

    Hit the refresh button (or wait until it segfaults, either way). The GUI will freeze and your gdb session will regain control. It'll say something about SIGSEGV. At that point, do a bt inside gdb, then copy it down somewhere and quit. The backtrace might be fairly long, though.

    I don't remember if gdb backtraces give you line numbers, but I think they do. If not, I might need a bit more help -- before you quit, do a list and give me the 10 lines of code that print out. Thanks!
    "If you fail to adjust your notion of fairness to the reality of the Universe, you will probably not be happy."

    -- Originally posted by Paratima

  6. #6
    Senior Member
    Join Date
    Mar 2002
    Location
    MI, U.S.
    Posts
    697
    Never mind, I can't attach it, apparently it's too big. Get it here:

    http://kadzban.is-a-geek.net/dfGUI-l...piled-debug.gz
    "If you fail to adjust your notion of fairness to the reality of the Universe, you will probably not be happy."

    -- Originally posted by Paratima

  7. #7
    Junior Member aptarasc's Avatar
    Join Date
    May 2003
    Location
    Folsom, CA
    Posts
    18
    Starting program: /home/andy/distribfold/dfGUI-3.2.1-precompiled-debug

    Program received signal SIGSEGV, Segmentation fault.
    0x4207a87b in strlen () from /lib/tls/libc.so.6

    (gdb) bt
    #0 0x4207a87b in strlen () from /lib/tls/libc.so.6
    #1 0x40440ae2 in g_strjoinv () from /usr/lib/libglib-2.0.so.0
    #2 0x0806c9f2 in update_error_log () at callbacks.c:703
    #3 0x0806f420 in refresh_timeout (data=0x0) at callbacks.c:1332
    #4 0x4042e4fc in g_main_context_wakeup () from /usr/lib/libglib-2.0.so.0
    #5 0x4042bb35 in g_get_current_time () from /usr/lib/libglib-2.0.so.0
    #6 0x4042cb78 in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
    #7 0x4042ce8d in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
    #8 0x4042d58f in g_main_loop_run () from /usr/lib/libglib-2.0.so.0
    #9 0x4012cf5f in gtk_main () from /usr/lib/libgtk-x11-2.0.so.0
    #10 0x0804eb1a in main (argc=1, argv=0xbfffdfa4) at main.c:59
    #11 0x42015704 in __libc_start_main () from /lib/tls/libc.so.6
    (gdb) list
    59 main.c: No such file or directory.
    in main.c

  8. #8
    Senior Member
    Join Date
    Mar 2002
    Location
    MI, U.S.
    Posts
    697
    Thanks. It looks like the "list" didn't do anything useful, because you don't have the actual source on your machine. But no big deal; I can see the line numbers.

    update_error_log (the function that grabs the last 30 lines of your error.log file and puts it into a textview) is calling g_strjoinv(). That's expected. That function is calling strlen() from the standard C library (BTW: though this doesn't appear to be an NPTL specific problem, I probably should figure out some way to do testing on an NPTL system like yours eventually... hmm...). strlen() is what's segfaulting. That shouldn't happen unless it's getting passed NULL or an invalid pointer from g_strjoinv()... interesting.

    Oh, I bet I know what the problem is. Does your error.log file have fewer than 30 lines in it? If so, then I've uploaded a new precompiled executable (to the same place as before) that should fix that case. It's still a debug version; if it works, I'll get rid of it and put a non-debug version up where you got your original version from. I'll also put up the new source.

    I never thought about that case originally. Basically, I read the contents of error.log into a string, called g_strsplit() on it (splitting on "\n") to make it into an array of strings (one for each line in the file). Then I counted the number of strings, and added (that number - 30) to the starting address of the array. This was supposed to make it so there were no more than 30 elements in the array, but what it ended up doing was making it so that there were always 30 elements in the array. The problem is, if error.log has fewer than 30 lines in it, then the first bunch of elements in the array are going to be random data -- most likely invalid pointers.

    Anyway, let me know if that fixes it. Sheesh.
    "If you fail to adjust your notion of fairness to the reality of the Universe, you will probably not be happy."

    -- Originally posted by Paratima

  9. #9
    Junior Member aptarasc's Avatar
    Join Date
    May 2003
    Location
    Folsom, CA
    Posts
    18
    Yup, that was the problem.

  10. #10
    Senior Member
    Join Date
    Mar 2002
    Location
    MI, U.S.
    Posts
    697
    OK, cool. Updated source is on the main site, if you want it. The "precompiled.bin" there is a non-debug version also (should be a slight bit faster, if it's noticeable at all).
    "If you fail to adjust your notion of fairness to the reality of the Universe, you will probably not be happy."

    -- Originally posted by Paratima

  11. #11
    The points tab still has some glitches in it.
    The "points per set" value still shows the old 50 structure value.

    And how is the "sets complete" calculated?
    I had a few sets buffered and each time dfGUI is closed the "sets complete" will show 0 sets upon restart. I'm not sure what this value actually represents but it looks like a proper description would be "sets completed in this dfGUI session"

    "points buffered" also has trouble getting the right score with multiple sets buffered and negative score values are pretty common.

  12. #12
    Senior Member
    Join Date
    Mar 2002
    Location
    MI, U.S.
    Posts
    697
    Originally posted by Hagar
    The "points per set" value still shows the old 50 structure value.
    You're right. That gets recalculated when focus leaves the "number of generations" textbox on the config screen, so a workaround is to click in there then click in some other textbox. The correct value then gets displayed.

    The default value that's displayed will get changed as soon as I upload the next patch-level version thingy.

    And how is the "sets complete" calculated?
    When dfGUI sees a transition from generation # "whatever generation you've got configured as the "Number of Generations" value (default is 250)" to 0, it increments the number of sets complete.

    I had a few sets buffered
    A few sets? As in like 750 generations? Goodness...

    and each time dfGUI is closed the "sets complete" will show 0 sets upon restart. I'm not sure what this value actually represents but it looks like a proper description would be "sets completed in this dfGUI session"
    Yeah, probably. Everything that you see in there is "in this dfGUI session", though -- it doesn't persist anything except your settings (the stuff on the config tabs).

    "points buffered" also has trouble getting the right score with multiple sets buffered and negative score values are pretty common.
    The points buffered gets calculated by taking the point value for each generation that the progress.txt file says is buffered. Basically, it's doing a really simple for loop on the variable i, running from <current gen> - <gens buffered according to progress.txt> + 1, up to <current gen>, adding <structures per generation> * sqrt(i) to the total each time. I'm pretty sure the problem is that progress.txt is indicating more generations buffered than what exist (which makes sense since you have more than one set buffered).

    I will have to make that a lot more intelligent. Let me figure out a good way to do it and I'll get back to this thread...

    Thanks!
    "If you fail to adjust your notion of fairness to the reality of the Universe, you will probably not be happy."

    -- Originally posted by Paratima

  13. #13
    Senior Member
    Join Date
    Mar 2002
    Location
    MI, U.S.
    Posts
    697
    OK, that should be better -- I hope. I split code execution based on whether there was any "overflow" from previous sets in the "gens buffered" parameter. If so, then it takes whatever's left over and repeatedly adds a full set's worth of points, then subtracts a full set's worth of gens. When it's left with less than a full set of gens, it takes that many gens' points (from the top of the range) and adds them to the total. I don't think I have any off-by-one errors in there anywhere.

    Let me know if it's still screwed up though.

    Download the fixed version at the same location as the previous.
    "If you fail to adjust your notion of fairness to the reality of the Universe, you will probably not be happy."

    -- Originally posted by Paratima

  14. #14
    yeah that's a lot better
    Just a few remarks, you forgot to subtract gen 0 from gen_overflow (each buffered set = 251 gens)
    so line 1041 of callbacks.c should be:
    Code:
    gen_overflow -= GUIconf.numGenerations + 1;
    And another is that if you have a complete set buffered and are working on gen 0 of the new set, "points buffered" will always have 100 extra points (the points for gen 0).

    I made some screenshots that will show this (with the above fix applied)
    http://basil.homelinux.net/~harm/dfGUI/

    And one thing led to another so I ended up rewriting the buffered points calculation and made a patch for it
    http://basil.homelinux.net/~harm/dfG...d-points.patch
    It seems to work fine for the situations I could come up with, but I'm still a novice so it needs to be verified

    Edit: applied small fix, if you got the patch before this edit get it again
    Last edited by Hagar; 01-04-2004 at 03:13 AM.

  15. #15
    Senior Member
    Join Date
    Mar 2002
    Location
    MI, U.S.
    Posts
    697
    Originally posted by Hagar
    yeah that's a lot better
    Just a few remarks, you forgot to subtract gen 0 from gen_overflow (each buffered set = 251 gens)
    so line 1041 of callbacks.c should be:
    Code:
    gen_overflow -= GUIconf.numGenerations + 1;
    Like I said -- I didn't think there were any off-by-one errors. Obviously there was one. Good catch!

    And another is that if you have a complete set buffered and are working on gen 0 of the new set, "points buffered" will always have 100 extra points (the points for gen 0).

    I made some screenshots that will show this (with the above fix applied)
    http://basil.homelinux.net/~harm/dfGUI/
    That is a problem. Minor, but it is a problem. Hmm...

    And one thing led to another so I ended up rewriting the buffered points calculation and made a patch for it
    I love open source. I'm pretty sure it would've taken me quite a while to come up with a fix for the previous.

    It seems to work fine for the situations I could come up with, but I'm still a novice so it needs to be verified
    OK, looking at it now.

    The only thing that I can see is, what if the user started to buffer generations at a generation number other than 0? It looks like the patch is just going to divide gens_buf by 251 -- but if they started buffering (or if the last flush was) on gen 150 for example, then they might only have 110 gens buffered according to progress.txt, but there will be one set buffered. The same issue is going to apply on the upper end of the buffered gens -- the modulo operator is going to make the code think there are 110 gens buffered in the last set, when there are only actually something like 9 or 10.

    Hmm... what if I did something like this?

    Code:
    if(cur_gen-gens_buf+1 >= 0) {
        for(i=cur_gen-gens_buf+1; i<cur_gen; i++)
            temp_ctr += (int)(STRUCTS_PER_GEN*sqrt(i));
    }
    else {
        int gen_overflow = gens_buf - cur_gen - 1;
    
        int set_overflow = (gen_overflow + GUIconf.numGenerations) / (GUIconf.numGenerations + 1);
        /* i.e., round up -- 1 to 251 becomes 1, 252 -> 502 becomes 2, etc. 
            This is the number of full or partial sets finished before the current one. */
    
        int gen_leftover = gen_overflow % (GUIconf.numGenerations + 1)
        /* This (^) is the number of gens at the tail end of the first buffered set. 
            We know that the tail end of gen_overflow is aligned on a set boundary now,
            so this should be valid.  Right? */
    
        for(i=0; i<set_overflow; i++) {
            if(i == 0) {  /* handle the first set specially */
                if(gen_leftover == 0)  /* then gen_overflow was aligned at the start too. */
                    temp_ctr += (int)STRUCTS_PER_GEN;  /* and we need to handle gen 0 */
    
                for(i=GUIconf.numGenerations - gen_leftover + 1; i<=GUIconf.numGenerations; i++)
                    temp_ctr += (int)(STRUCTS_PER_GEN * sqrt(i));
            }
            else {
                temp_ctr += (int)STRUCTS_PER_GEN;
    
                for(i=1; i<=GUIconf.numGenerations; i++)
                    temp_ctr += (int)(STRUCTS_PER_GEN * sqrt(i));
            }
        }
    }
    Does that get rid of the problems when you're currently on gen 0, or not?
    "If you fail to adjust your notion of fairness to the reality of the Universe, you will probably not be happy."

    -- Originally posted by Paratima

  16. #16
    Originally posted by bwkaz
    Like I said -- I didn't think there were any off-by-one errors. Obviously there was one. Good catch!

    That is a problem. Minor, but it is a problem. Hmm...

    I love open source. I'm pretty sure it would've taken me quite a while to come up with a fix for the previous.

    OK, looking at it now.

    The only thing that I can see is, what if the user started to buffer generations at a generation number other than 0? It looks like the patch is just going to divide gens_buf by 251 -- but if they started buffering (or if the last flush was) on gen 150 for example, then they might only have 110 gens buffered according to progress.txt, but there will be one set buffered. The same issue is going to apply on the upper end of the buffered gens -- the modulo operator is going to make the code think there are 110 gens buffered in the last set, when there are only actually something like 9 or 10.

    Hmm... what if I did something like this?

    Code:
    ...
    Does that get rid of the problems when you're currently on gen 0, or not?
    no
    Code:
    if(i == 0) {  /* handle the first set specially */
                if(gen_leftover == 0)  /* then gen_overflow was aligned at the start too. */
                    temp_ctr += (int)STRUCTS_PER_GEN;  /* and we need to handle gen 0 */
    
                for(i=GUIconf.numGenerations - gen_leftover + 1; i<=GUIconf.numGenerations; i++)
                    temp_ctr += (int)(STRUCTS_PER_GEN * sqrt(i));
            }
    this breaks if gen_leftover = 0 because the loop only works for partial sets.
    if you have 1005 gens buffered and are working on gen0 you'd miss out on a whole set -100 points.

    the current set doesn't get accounted for at all.

    So after some small adjustments I got this.
    I think this will work for all situations.
    Code:
    		if(cur_gen-gens_buf+1 >= 0) {
    			for(i=cur_gen-gens_buf+1; i<cur_gen; i++)
    				temp_ctr += (int)(STRUCTS_PER_GEN*sqrt(i));
    		}
    		else {
    			int j; /* took some time before I realised you had the same iterator in a nested loop :) */
    			int gen_overflow = gens_buf - cur_gen - 1;
    
    			int set_overflow = (gen_overflow + GUIconf.numGenerations) / (GUIconf.numGenerations + 1);
    			/* i.e., round up -- 1 to 251 becomes 1, 252 -> 502 becomes 2, etc. 
    			This is the number of full or partial sets finished before the current one. */
    
    			int gen_leftover = gen_overflow % (GUIconf.numGenerations + 1);
    			/* This (^) is the number of gens at the tail end of the first buffered set. 
    			We know that the tail end of gen_overflow is aligned on a set boundary now,
    			so this should be valid.  Right? */
    
    			for(i=0; i<set_overflow; i++) {
    				if(i == 0 && gen_leftover != 0) {
    					/* handle the first set specially unless there is no overflow (no partial first set)
    					gen 0 is not needed because it's a partial first set */
    					for(j=GUIconf.numGenerations - gen_leftover + 1; j<=GUIconf.numGenerations; j++)
    						temp_ctr += (int)(STRUCTS_PER_GEN * sqrt(j));
    				}
    				else {
    					temp_ctr += (int)STRUCTS_PER_GEN;
    
    					for(j=1; j<=GUIconf.numGenerations; j++)
    						temp_ctr += (int)(STRUCTS_PER_GEN * sqrt(j));
    				}
    			}
    			/* continue with points for the gens in the current set
    			only add points for gen 0 if it's finished */
    			if(cur_gen > 0)
    				temp_ctr += (int)STRUCTS_PER_GEN;
    			for(i=1; i<cur_gen; i++)
    				temp_ctr += (int)(STRUCTS_PER_GEN*sqrt(i));
    			
    		}
    Edit: ok, I tested it for the situations I used for my previous code and the buffered first partial set. Every thing seems to work.
    Last edited by Hagar; 01-05-2004 at 05:51 PM.

  17. #17
    Senior Member
    Join Date
    Mar 2002
    Location
    MI, U.S.
    Posts
    697
    Originally posted by Hagar
    Code:
    			int j; /* took some time before I realised you had the same iterator in a nested loop :) */
    Oh good grief...

    I really need to look at my code a bit more. Good catch!

    Edit: ok, I tested it for the situations I used for my previous code and the buffered first partial set. Every thing seems to work.
    Yeah, it looks to me like everything should work now, too. Not having any set_overflow is taken care of with the first if, so the inner i for loop looks OK, too (though not at first glance).

    Check your PM's -- once I get a response to that all-important question (basically, it's "can I release this?", but there are some finer points), I'll put up a fixed version of the code.
    "If you fail to adjust your notion of fairness to the reality of the Universe, you will probably not be happy."

    -- Originally posted by Paratima

  18. #18
    Senior Member
    Join Date
    Mar 2002
    Location
    MI, U.S.
    Posts
    697
    New release in the same location as before. (Yes, I know, I should bump it to 3.2.2... oh well, too late now.)

    Thanks again for all the help, Hagar.
    "If you fail to adjust your notion of fairness to the reality of the Universe, you will probably not be happy."

    -- Originally posted by Paratima

  19. #19
    Sometimes my dfGUI for Linux just disappears in a minute after being run.
    The other problem is that it doesn't log the history of generations. The check is disabled and I just cant check it to log.

  20. #20
    Senior Member
    Join Date
    Mar 2002
    Location
    MI, U.S.
    Posts
    697
    Originally posted by zenk
    Sometimes my dfGUI for Linux just disappears in a minute after being run.
    Can you run it from a terminal, and reproduce from there? That way you'll get the actual error message that it's most likely giving you (if you don't run it from a terminal, though, that error won't have anywhere to go, so you won't see it).

    The other problem is that it doesn't log the history of generations. The check is disabled and I just cant check it to log.
    See the TODO file -- it's because I didn't see the point when I first did the port. You're the first one to say anything about it.

    What do you want it to log? I can try to get it in there before releasing 3.3 (though it probably won't be too hard to do).
    "If you fail to adjust your notion of fairness to the reality of the Universe, you will probably not be happy."

    -- Originally posted by Paratima

  21. #21
    (dfGUI:10214): GLib-CRITICAL **: file gstrfuncs.c: line 2096 (g_strchomp): assertion `string != NULL' failed

    (dfGUI:10214): GLib-CRITICAL **: file gstrfuncs.c: line 2143 (g_strsplit): assertion `string != NULL' failed
    Segmentation fault

    I want to log the energy, so I can see the graph of the generations I made before when I restart dfGUI

  22. #22
    Senior Member
    Join Date
    Mar 2002
    Location
    MI, U.S.
    Posts
    697
    Do you want to go back more than one set? I hope not, because I don't really have any way of doing that (that's why the "reset graph after final generation" checkbox is checked and disabled -- it's not really available as a preference).

    I can log each generation's time and energy, though, and then reset it at the end of a set (and also pull it in at startup). That's not a huge deal.

    As for the other problems (the failed assertions, then the segfault), based on the glib code in question, it looks like g_spawn_sync is probably failing on your machine for some reason... hmm. Because when it fails, it sets "out" to NULL, and "out" is what's getting passed to g_strchomp and g_strsplit (and it's NULL when those functions see it).

    So, the question is, why would it fail? Do you have a /bin/pidof executable? If not, is your pidof executable somewhere else? (Try type -p pidof in bash; if it doesn't find it, look in /sbin or /usr/sbin or /usr/local/sbin manually.) If you still can't find it, try something like a find / -name pidof -- but beware, it'll take quite a long time.

    If your pidof is in /usr/bin, then I'll need to make the location of pidof a configure-time check (which even further reduces the portability of the binary... but oh well though).

    Actually, if this is on Slackware, then since Slackware uses BSD init, you might not even have a pidof executable. I know one version of pidof is a part of the sysvinit package, and I think another, slightly inferior, version is part of the psmisc package. That's a fairly huge problem if it's the case...
    "If you fail to adjust your notion of fairness to the reality of the Universe, you will probably not be happy."

    -- Originally posted by Paratima

  23. #23
    The log for the set is enough.
    pidof is in /sbin
    My distribution of Linux is Mandrake 9.2

  24. #24
    Senior Member
    Join Date
    Mar 2002
    Location
    MI, U.S.
    Posts
    697
    /sbin -- OK, the program is hardcoded to look in /bin (since it doesn't make any sense to not allow users to find the PIDs of their processes, I'm wondering why Mandrake chose to put it in /sbin, but whatever). That's the problem.

    Umm... if you've got the source you can fix it for now by changing "/bin/pidof" to "/sbin/pidof" in src/callbacks.c (near line 470 or so, I think). Or, you can symlink /sbin/pidof into /bin just to make the program happy, but that's obviously not a permanent solution.

    The permanent solution is for me to check at configure time where your pidof executable is located. I'll do that in 3.3 (actually the code's already there, I did it last night, but I don't plan on releasing it until 3.3). I should probably also do the same thing with free and ps (right now free is hardcoded as /usr/bin/free and ps is hardcoded as /bin/ps). It's fairly simple to change those, though.

    As for the logging, sounds good.
    "If you fail to adjust your notion of fairness to the reality of the Universe, you will probably not be happy."

    -- Originally posted by Paratima

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •