You are not logged in.

#1 2012-09-13 13:29:48

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

[SOLVED] A DWM statusbar in C

Hello,

On Trilby's GitHub I found a little C program that would set DWM's statusbar. I think this is a) alot cleaner than using a bashcript with ask, sed, pipes etc and b) a nice practice for me to learn some C.

I have been messing around with it and want to add a few things, but first, it's segfaulting on the battery part. Note that I have not edited this part. I already send Trilby an email yesterday but he hasn't replied so far.

Here's the code related to the battery part:

#define BATT_LOW	11 // Below BATT_LOW percentage left on battery, the battery display turns red
#define BATT_NOW		"/sys/class/power_supply/BAT1/charge_now"
#define BATT_FULL		"/sys/class/power_supply/BAT1/charge_full"
#define BATT_STAT		"/sys/class/power_supply/BAT1/status"

...

	// Power / Battery
		infile = fopen(BATT_NOW,"r");
			fscanf(infile,"%ld\n",&lnum1); fclose(infile);
		infile = fopen(BATT_FULL,"r");
			fscanf(infile,"%ld\n",&lnum2); fclose(infile);
		infile = fopen(BATT_STAT,"r");
			fscanf(infile,"%s\n",statnext); fclose(infile);
		num = lnum1*100/lnum2;
		if (strncmp(statnext,"Charging",8) == 0) {
			sprintf(statnext,BAT_CHRG_STR,num);
		}
		else {
			if (num < BATT_LOW)
				sprintf(statnext,BAT_LOW_STR,num);
			else
				sprintf(statnext,BAT_STR,num);
		}
		strcat(status,statnext);

I have run gdb and found out that the error is somewhere in

		infile = fopen(BATT_NOW,"r");
			fscanf(infile,"%ld\n",&lnum1); fclose(infile);
		infile = fopen(BATT_FULL,"r");
			fscanf(infile,"%ld\n",&lnum2); fclose(infile);
		infile = fopen(BATT_STAT,"r");
			fscanf(infile,"%s\n",statnext); fclose(infile);

When I comment that out and run it, it indeed doesn't segfault where it would with this uncommented.
Here's gdb's backtrace:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff755b69a in __isoc99_fscanf () from /usr/lib/libc.so.6

I already checked and do have /usr/lib/libc.so.6, so what is causing this segfault?

PS: I'm trying to implement WiFi ESSID and signal, but I can't find a file in sysfs that has these settings. Is there such a file that I can use? If not, is there a simple way to retrieve WiFi ESSID and print it?

EDIT: I do have those battery related files in sysfs.

Last edited by Unia (2012-12-19 00:01:59)


If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

#2 2012-09-13 13:37:01

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,441
Website

Re: [SOLVED] A DWM statusbar in C

Glad my hack inspired you to try your own.  As I've stopped using dwm regularly, I haven't looked at this app in a while.  Also, as I tinker with my tools a lot, they are prone to breakage.

I'll check this out later today and see what I screwed up.  My first thought, though, before any testing is that perhaps your battery files are different.  Sometimes they are BATT0, sometimes they are BATT1.  I believe the path should remain the same, but this too could be checked.

My app had no error checking to work on different systems as it was a shorthand hack to work for me.  In a properly made and distributed version each fopen should be checked for success.  This could be something like:

    if ( (infile=fopen(BATT_NOW,"r") )
        fscanf(...

"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#3 2012-09-13 13:40:00

lunar
Member
Registered: 2010-10-04
Posts: 95

Re: [SOLVED] A DWM statusbar in C

Please show the complete source code.  GDB has pointed you only to where the bug is triggered, but that is not necessarily where the bug is caused.

Check the return values and `errno` from `fopen()` and `fscanf()` to catch and handle errors.

Offline

#4 2012-09-13 13:47:40

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,441
Website

Re: [SOLVED] A DWM statusbar in C

Unia, I suspect the problem is from the audio info.  This is a very ugly kludge I used, but it traded off stability for a massive savings in resource use.  It is perfectly stable when everything is set up just the way the program expects.

There needs to be a file in where you pont AUD_FILE which includes a single number between -1 and 100.  0 to 100 indicate an audio volume, -1 indicates audio is muted.

I have keybindings for my volume buttons to set the volume through amixer and to also store the current value in that file.  If this file does not exist, or includes anything other than this single numerical value, the statusbar will segfault.  Again, this is an ugly kludge, but the alternative seemed to be to poll alsa every second for a value that only rarely changes thus starting a new process, reading data, parsing data, etc.

I do get a segfault when that file is missing.  When the file is present and properly storing a number, the status bar works.

If you're tinkering, the audio information would be a great place to come up with a better solution.

PS: sorry if I missed an email.  I should change the email associated with the forum if possible.  I used my for-online-accounts email which I only check periodically.  Now that I feel more part of this community and know that my email does not get spammed by the BB software of the arch community I'll change it to my daily email (if possible).  Until then, I can be reached best at the email at the top of any of my PKGBUILDS (eg leela-git, ttwm-git).

Last edited by Trilby (2012-09-13 13:51:38)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#5 2012-09-13 14:01:54

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

Re: [SOLVED] A DWM statusbar in C

Trilby wrote:

I'll check this out later today and see what I screwed up.  My first thought, though, before any testing is that perhaps your battery files are different.  Sometimes they are BATT0, sometimes they are BATT1.  I believe the path should remain the same, but this too could be checked.

Yes, I have the same battery files.

lunar wrote:

Please show the complete source code.  GDB has pointed you only to where the bug is triggered, but that is not necessarily where the bug is caused.

Excuse me, here's the complete code:
https://gist.github.com/3714507

Trilby wrote:

Unia, I suspect the problem is from the audio info.  This is a very ugly kludge I used, but it traded off stability for a massive savings in resource use.  It is perfectly stable when everything is set up just the way the program expects.

There needs to be a file in where you pont AUD_FILE which includes a single number between -1 and 100.  0 to 100 indicate an audio volume, -1 indicates audio is muted.

I have keybindings for my volume buttons to set the volume through amixer and to also store the current value in that file.  If this file does not exist, or includes anything other than this single numerical value, the statusbar will segfault.  Again, this is an ugly kludge, but the alternative seemed to be to poll alsa every second for a value that only rarely changes thus starting a new process, reading data, parsing data, etc.

I do get a segfault when that file is missing.  When the file is present and properly storing a number, the status bar works.

If you're tinkering, the audio information would be a great place to come up with a better solution.

For now I have the audio section commented out, because I couldn't find the script you were using to store values in the AUD_FILE. I did find it now in your ttwm repo and a quick test shows that it works, but even then it would segfault with the batteries.

It's oke you missed the email, we're talking now anyway big_smile

EDIT: Could you share the keybinding settings that you use to store the values in the file? I think this is cleaner than the script.

Last edited by Unia (2012-09-13 14:03:24)


If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

#6 2012-09-13 14:08:14

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,441
Website

Re: [SOLVED] A DWM statusbar in C

Sure, if you mean my dwm bindings which just call the "vol" script:

    { 0,            0x1008ff11,     spawn,      SHCMD("vol down") },
    { 0,            0x1008ff13,     spawn,      SHCMD("vol up") },
    { 0,            0x1008ff12,     spawn,      SHCMD("vol toggle") },

But any manner of setting volume that follows the same "rules" for that audio file should work.

If it's not the audio, I'm not sure what's wrong as it works here.  But I will spend a bit more time with it tonight to see if I can spot anything.

EDIT: the 0x1008ffXX are usually the appropriate key codes for the relevant "media buttons", but these might differ on some machines.  Xev will answer that.

Last edited by Trilby (2012-09-13 14:09:19)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#7 2012-09-13 14:39:37

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

Re: [SOLVED] A DWM statusbar in C

^ Thanks, got it.


If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

#8 2012-09-14 14:41:12

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

Re: [SOLVED] A DWM statusbar in C

Meh... can you believe this! It turns out the path was indeed wrong! >< I shouldn't try coding when I'm not completely focused! I have BAT0, instead of BAT1. Stupid me only checked if it were BAT or ADP, I didn't check the numbers......

Before I'm off to a corner to put some shame on myself, does any of you know a file that holds the ESSID for the network and the signal strength, or some other way to retreive this using C?


If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

#9 2012-09-14 16:34:17

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,441
Website

Re: [SOLVED] A DWM statusbar in C

You can get information about actual data transmission rates from /sys/class/net/<interface>/statistics/* where <interface> might be wlan0 or eth0, etc.

However this will not give signal strength nor potential transmission speeds as (AFAIK) it is only actual transmitted data.

If you really want that data, I'd suggest reading from a popen("iwconfig wlan0","r") or similar.  This does create an additional process, but it is fairly quick and light.  Perhaps you'd not do this every time through the loop (eg every second) but only do it every minute or so.

Alternately, you could use the same thinking I did for my audio information: as this is data that is much less "dynamic" you could have your own data file that stores the network name and signal strength.  Then, perhaps you could have that file rewriten every time there is a change in network settings.  Some network apps have "hooks" or scripts that can run before or after a connection is made.  These could write the network name and strength to a file which your status bar app just reads from.

Last edited by Trilby (2012-09-14 16:39:12)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#10 2012-09-14 18:39:32

moetunes
Member
From: A comfortable couch
Registered: 2010-10-09
Posts: 1,033

Re: [SOLVED] A DWM statusbar in C

This finds most of the wifi's info. I made it while sorting out my own program for system info.
HTH.


You're just jealous because the voices only talk to me.

Offline

#11 2012-09-14 18:46:16

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

Re: [SOLVED] A DWM statusbar in C

moetunes wrote:

This finds most of the wifi's info. I made it while sorting out my own program for system info.
HTH.

I had looked at that already, yea. Thing is, that whole thing to get ESSID and signal strength is longer than what I currently have for battery, date and volume together - so before I would go that way, I wanted to see if there's something simpler.

Could I somehow simplify that WiFi thing?


If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

#12 2012-09-14 19:44:35

moetunes
Member
From: A comfortable couch
Registered: 2010-10-09
Posts: 1,033

Re: [SOLVED] A DWM statusbar in C

To find the sort of info you want you need to use the iw api. I couldn't find any other way.
Unless you want to rewrite that there's only one way to use it.
You just need to define a structure, fill it and then pull info from it. You can see from the commented lines in wireless.c that I don't use all the info so you can just use the bits you need.
Why is the 'length' of it relevant to you? It's not slow, cpu intensive or a memory hog.


You're just jealous because the voices only talk to me.

Offline

#13 2012-09-14 20:16:07

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

Re: [SOLVED] A DWM statusbar in C

moetunes wrote:

To find the sort of info you want you need to use the iw api. I couldn't find any other way.
Unless you want to rewrite that there's only one way to use it.

If I would know how, maaaybe I'd give it a go tongue

moetunes wrote:

You just need to define a structure, fill it and then pull info from it. You can see from the commented lines in wireless.c that I don't use all the info so you can just use the bits you need.
Why is the 'length' of it relevant to you? It's not slow, cpu intensive or a memory hog.

I guess that shows I don't really know any C yet, I compare it to bash: the longer, the more memory/cpu and the slower.. usually. I will look into your WiFi and see if I can get it to work.

For now, I started working on implementing MPD. I got it to build without errors, but again a SIGSEGV when I run it (also tried with MPD running, but still SIGSEGV). Here's the new code and backtrace from GDB, should anyone want to give it a go:

Code: https://gist.github.com/3724450
Backtrace:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7898b05 in mpd_recv_pair ()
   from /usr/lib/libmpdclient.so.2

If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

#14 2012-09-14 22:45:33

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,441
Website

Re: [SOLVED] A DWM statusbar in C

*note to self: learn iwlib*

moetunes' code looks great.  While having few lines of code is often a fun "marketing" ploy, it is not much of a representation of resource use.  My suggestion would only be a couple lines of code, but you'd be starting a new process (iwconfig) with its own code ... so that'd be using far more lines of code anyway.


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#15 2012-09-14 22:54:51

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

Re: [SOLVED] A DWM statusbar in C

Trilby wrote:

*note to self: learn iwlib*

moetunes' code looks great.  While having few lines of code is often a fun "marketing" ploy, it is not much of a representation of resource use.  My suggestion would only be a couple lines of code, but you'd be starting a new process (iwconfig) with its own code ... so that'd be using far more lines of code anyway.

Another thing learned smile I had already started working on Moetunes' code, since I don't know what's wrong with my MPD part. I've already slimmed it down to what I'd need from it, now I just have to adapt it to work with what I currently have.

But that's for tomorrow (exciting day: first driver's lesson!). In the meantime, can someone help me with the MPD part?

I'd also like to thank everyone that has replied! It's coming together now! smile


If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

#16 2012-09-14 23:01:08

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,441
Website

Re: [SOLVED] A DWM statusbar in C

Two things jump out: first should "have_song" be reset to zero at the end of each loop?  I'm not really sure as I'm not familiar with that function.

More importantly, I tried to be efficient with the size of the status string.  I allocated a certain number of characters for it, and used most of them.  If you are adding more to the string without increasing it's storage space, that would lead to a segfault.


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#17 2012-09-15 00:04:31

karol
Archivist
Registered: 2009-05-06
Posts: 25,440

Re: [SOLVED] A DWM statusbar in C

Unia wrote:

But that's for tomorrow (exciting day: first driver's lesson!).

My first lesson (car driving license) was rather uneventful as I was "confined" to the parking lot, getting grip on the basic maneuvers.
In the second lesson I was thrown at the deep end - I was told to drive to the busy city centre. It was just a short downhill drive, but the hill was rather steep and I was going at the break-neck speed of 40 km/h!
I've known fear.


I've noticed that the status doesn't get cleared after dwmStatus gets terminated f.e. it still shows the (now wrong) time and date.

Offline

#18 2012-09-15 00:07:35

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,441
Website

Re: [SOLVED] A DWM statusbar in C

karol wrote:

I've noticed that the status doesn't get cleared after dwmStatus gets terminated f.e. it still shows the (now wrong) time and date.

Well that's a simple fix: don't terminate it! wink

Or just put this at the end

XStoreName(dpy,root,"");

edit: this is, of course, only relevant if dwmStatus exits normally.  But as it will never exit normally .... this wouldn't serve much purpose. (life jackets on a deep sea vehicle?)

If you wanted to implement this, dwmStatus would have to listen for a signal or event to tell it to shut down nicely.  I never had any use for such a thing.

A much more practical solution would be to envoke it as follows:

dwmStatus || xsetroot --name "Empy" &

This way if there is an unanticipated error in dwmStatus - or if it is killed - the root window name will be set to "empty" or whatever else.

Last edited by Trilby (2012-09-15 00:17:22)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#19 2012-09-15 00:52:41

karol
Archivist
Registered: 2009-05-06
Posts: 25,440

Re: [SOLVED] A DWM statusbar in C

Trilby wrote:
karol wrote:

I've noticed that the status doesn't get cleared after dwmStatus gets terminated f.e. it still shows the (now wrong) time and date.

Well that's a simple fix: don't terminate it! wink

As it's expected to run the whole time, I guess this is the right answer :-)


I'm using hesse's dwmst. He also has some scripts, like the one for audio: https://github.com/htor/linux/blob/master/bin/vol

Offline

#20 2012-09-15 09:24:20

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

Re: [SOLVED] A DWM statusbar in C

karol wrote:

My first lesson (car driving license) was rather uneventful as I was "confined" to the parking lot, getting grip on the basic maneuvers.
In the second lesson I was thrown at the deep end - I was told to drive to the busy city centre. It was just a short downhill drive, but the hill was rather steep and I was going at the break-neck speed of 40 km/h!
I've known fear.

lol

I have already practiced a bit with my parents (sshhtt, don't tell! We're actually not allowed to big_smile) so it's not really my first time on the driver's seat. Still, this is the first time I'll be on a road with other vehicles.

Trilby, what line should I increase the storage space? Already tried changing statnext and/or status, but it still segfaults.


If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

#21 2012-09-15 09:25:45

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

Re: [SOLVED] A DWM statusbar in C

karol wrote:

I'm using hesse's dwmst. He also has some scripts, like the one for audio: https://github.com/htor/linux/blob/master/bin/vol

Yep, I have it bookmarked to refer to if something's not working big_smile Thanks!


If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

#22 2012-09-15 10:11:17

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

Re: [SOLVED] A DWM statusbar in C

Got a little further again! I succesfully managed to shorten Moetunes' code and adopted it to what I currently have. When I run the program, it does show the ESSID and signal percentage, but quits after ~1 second. I guess this is because it's updating too fast and thus flows too much data through the program? If that's the case (error messages from terminal this time, see below), how can I set an individual sleep for the ESSID and signal percentage, so that it gets updates every minute?

EDIT: Here's the current code: https://gist.github.com/3727252

Error messages from terminal:

┌─[jente @ lappy dwm-status] 12:06:41 
└─■ ./dwmStatus
*** glibc detected *** ./dwmStatus: double free or corruption (!prev): 0x000000000182d010 ***
======= Backtrace: =========
/usr/lib/libc.so.6(+0x798a6)[0x7fe0957458a6]
./dwmStatus[0x40102f]
/usr/lib/libc.so.6(__libc_start_main+0xf5)[0x7fe0956ed725]
./dwmStatus[0x400d99]
======= Memory map: ========
00400000-00402000 r-xp 00000000 08:02 36438020                           /home/jente/abs/dwm-status/dwmStatus
00601000-00602000 rw-p 00001000 08:02 36438020                           /home/jente/abs/dwm-status/dwmStatus
0182d000-0184e000 rw-p 00000000 00:00 0                                  [heap]
7fe094990000-7fe0949a5000 r-xp 00000000 08:01 266885                     /usr/lib/libgcc_s.so.1
7fe0949a5000-7fe094ba4000 ---p 00015000 08:01 266885                     /usr/lib/libgcc_s.so.1
7fe094ba4000-7fe094ba5000 rw-p 00014000 08:01 266885                     /usr/lib/libgcc_s.so.1
7fe094ba5000-7fe094baa000 r-xp 00000000 08:01 280419                     /usr/lib/libXdmcp.so.6.0.0
7fe094baa000-7fe094da9000 ---p 00005000 08:01 280419                     /usr/lib/libXdmcp.so.6.0.0
7fe094da9000-7fe094daa000 r--p 00004000 08:01 280419                     /usr/lib/libXdmcp.so.6.0.0
7fe094daa000-7fe094dab000 rw-p 00005000 08:01 280419                     /usr/lib/libXdmcp.so.6.0.0
7fe094dab000-7fe094dad000 r-xp 00000000 08:01 280474                     /usr/lib/libXau.so.6.0.0
7fe094dad000-7fe094fad000 ---p 00002000 08:01 280474                     /usr/lib/libXau.so.6.0.0
7fe094fad000-7fe094fae000 r--p 00002000 08:01 280474                     /usr/lib/libXau.so.6.0.0
7fe094fae000-7fe094faf000 rw-p 00003000 08:01 280474                     /usr/lib/libXau.so.6.0.0
7fe094faf000-7fe0950a8000 r-xp 00000000 08:01 263872                     /usr/lib/libm-2.16.so
7fe0950a8000-7fe0952a7000 ---p 000f9000 08:01 263872                     /usr/lib/libm-2.16.so
7fe0952a7000-7fe0952a8000 r--p 000f8000 08:01 263872                     /usr/lib/libm-2.16.so
7fe0952a8000-7fe0952a9000 rw-p 000f9000 08:01 263872                     /usr/lib/libm-2.16.so
7fe0952a9000-7fe0952aa000 rw-p 00000000 00:00 0 
7fe0952aa000-7fe0952ad000 r-xp 00000000 08:01 263905                     /usr/lib/libdl-2.16.so
7fe0952ad000-7fe0954ac000 ---p 00003000 08:01 263905                     /usr/lib/libdl-2.16.so
7fe0954ac000-7fe0954ad000 r--p 00002000 08:01 263905                     /usr/lib/libdl-2.16.so
7fe0954ad000-7fe0954ae000 rw-p 00003000 08:01 263905                     /usr/lib/libdl-2.16.so
7fe0954ae000-7fe0954cb000 r-xp 00000000 08:01 280525                     /usr/lib/libxcb.so.1.1.0
7fe0954cb000-7fe0956cb000 ---p 0001d000 08:01 280525                     /usr/lib/libxcb.so.1.1.0
7fe0956cb000-7fe0956cc000 rw-p 0001d000 08:01 280525                     /usr/lib/libxcb.so.1.1.0
7fe0956cc000-7fe09586a000 r-xp 00000000 08:01 263890                     /usr/lib/libc-2.16.so
7fe09586a000-7fe095a69000 ---p 0019e000 08:01 263890                     /usr/lib/libc-2.16.so
7fe095a69000-7fe095a6d000 r--p 0019d000 08:01 263890                     /usr/lib/libc-2.16.so
7fe095a6d000-7fe095a6f000 rw-p 001a1000 08:01 263890                     /usr/lib/libc-2.16.so
7fe095a6f000-7fe095a73000 rw-p 00000000 00:00 0 
7fe095a73000-7fe095a85000 r-xp 00000000 08:01 289536                     /usr/lib/libmpdclient.so.2.0.5
7fe095a85000-7fe095c85000 ---p 00012000 08:01 289536                     /usr/lib/libmpdclient.so.2.0.5
7fe095c85000-7fe095c86000 r--p 00012000 08:01 289536                     /usr/lib/libmpdclient.so.2.0.5
7fe095c86000-7fe095c87000 rw-p 00013000 08:01 289536                     /usr/lib/libmpdclient.so.2.0.5
7fe095c87000-7fe095c8f000 r-xp 00000000 08:01 278692                     /usr/lib/libiw.so.29
7fe095c8f000-7fe095e8e000 ---p 00008000 08:01 278692                     /usr/lib/libiw.so.29
7fe095e8e000-7fe095e8f000 rw-p 00007000 08:01 278692                     /usr/lib/libiw.so.29
7fe095e8f000-7fe095fc2000 r-xp 00000000 08:01 281434                     /usr/lib/libX11.so.6.3.0
7fe095fc2000-7fe0961c2000 ---p 00133000 08:01 281434                     /usr/lib/libX11.so.6.3.0
7fe0961c2000-7fe0961c3000 r--p 00133000 08:01 281434                     /usr/lib/libX11.so.6.3.0
7fe0961c3000-7fe0961c8000 rw-p 00134000 08:01 281434                     /usr/lib/libX11.so.6.3.0
7fe0961c8000-7fe0961e9000 r-xp 00000000 08:01 263930                     /usr/lib/ld-2.16.so
7fe0963c6000-7fe0963cb000 rw-p 00000000 00:00 0 
7fe0963e8000-7fe0963e9000 rw-p 00000000 00:00 0 
7fe0963e9000-7fe0963ea000 r--p 00021000 08:01 263930                     /usr/lib/ld-2.16.so
7fe0963ea000-7fe0963eb000 rw-p 00022000 08:01 263930                     /usr/lib/ld-2.16.so
7fe0963eb000-7fe0963ec000 rw-p 00000000 00:00 0 
7ffff3602000-7ffff3623000 rw-p 00000000 00:00 0                          [stack]
7ffff37d3000-7ffff37d4000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Afgebroken

Backtrace from gdb:

Starting program: /home/jente/abs/dwm-status/dwmStatus 
warning: Could not load shared library symbols for linux-vdso.so.1.
Do you need "set solib-search-path" or "set sysroot"?
*** glibc detected *** /home/jente/abs/dwm-status/dwmStatus: double free or corruption (!prev): 0x0000000000602010 ***
======= Backtrace: =========
/usr/lib/libc.so.6(+0x798a6)[0x7ffff73588a6]
/home/jente/abs/dwm-status/dwmStatus[0x40102f]
/usr/lib/libc.so.6(__libc_start_main+0xf5)[0x7ffff7300725]
/home/jente/abs/dwm-status/dwmStatus[0x400d99]
======= Memory map: ========
00400000-00402000 r-xp 00000000 08:02 36438020                           /home/jente/abs/dwm-status/dwmStatus
00601000-00602000 rw-p 00001000 08:02 36438020                           /home/jente/abs/dwm-status/dwmStatus
00602000-00623000 rw-p 00000000 00:00 0                                  [heap]
7ffff65a3000-7ffff65b8000 r-xp 00000000 08:01 266885                     /usr/lib/libgcc_s.so.1
7ffff65b8000-7ffff67b7000 ---p 00015000 08:01 266885                     /usr/lib/libgcc_s.so.1
7ffff67b7000-7ffff67b8000 rw-p 00014000 08:01 266885                     /usr/lib/libgcc_s.so.1
7ffff67b8000-7ffff67bd000 r-xp 00000000 08:01 280419                     /usr/lib/libXdmcp.so.6.0.0
7ffff67bd000-7ffff69bc000 ---p 00005000 08:01 280419                     /usr/lib/libXdmcp.so.6.0.0
7ffff69bc000-7ffff69bd000 r--p 00004000 08:01 280419                     /usr/lib/libXdmcp.so.6.0.0
7ffff69bd000-7ffff69be000 rw-p 00005000 08:01 280419                     /usr/lib/libXdmcp.so.6.0.0
7ffff69be000-7ffff69c0000 r-xp 00000000 08:01 280474                     /usr/lib/libXau.so.6.0.0
7ffff69c0000-7ffff6bc0000 ---p 00002000 08:01 280474                     /usr/lib/libXau.so.6.0.0
7ffff6bc0000-7ffff6bc1000 r--p 00002000 08:01 280474                     /usr/lib/libXau.so.6.0.0
7ffff6bc1000-7ffff6bc2000 rw-p 00003000 08:01 280474                     /usr/lib/libXau.so.6.0.0
7ffff6bc2000-7ffff6cbb000 r-xp 00000000 08:01 263872                     /usr/lib/libm-2.16.so
7ffff6cbb000-7ffff6eba000 ---p 000f9000 08:01 263872                     /usr/lib/libm-2.16.so
7ffff6eba000-7ffff6ebb000 r--p 000f8000 08:01 263872                     /usr/lib/libm-2.16.so
7ffff6ebb000-7ffff6ebc000 rw-p 000f9000 08:01 263872                     /usr/lib/libm-2.16.so
7ffff6ebc000-7ffff6ebd000 rw-p 00000000 00:00 0 
7ffff6ebd000-7ffff6ec0000 r-xp 00000000 08:01 263905                     /usr/lib/libdl-2.16.so
7ffff6ec0000-7ffff70bf000 ---p 00003000 08:01 263905                     /usr/lib/libdl-2.16.so
7ffff70bf000-7ffff70c0000 r--p 00002000 08:01 263905                     /usr/lib/libdl-2.16.so
7ffff70c0000-7ffff70c1000 rw-p 00003000 08:01 263905                     /usr/lib/libdl-2.16.so
7ffff70c1000-7ffff70de000 r-xp 00000000 08:01 280525                     /usr/lib/libxcb.so.1.1.0
7ffff70de000-7ffff72de000 ---p 0001d000 08:01 280525                     /usr/lib/libxcb.so.1.1.0
7ffff72de000-7ffff72df000 rw-p 0001d000 08:01 280525                     /usr/lib/libxcb.so.1.1.0
7ffff72df000-7ffff747d000 r-xp 00000000 08:01 263890                     /usr/lib/libc-2.16.so
7ffff747d000-7ffff767c000 ---p 0019e000 08:01 263890                     /usr/lib/libc-2.16.so
7ffff767c000-7ffff7680000 r--p 0019d000 08:01 263890                     /usr/lib/libc-2.16.so
7ffff7680000-7ffff7682000 rw-p 001a1000 08:01 263890                     /usr/lib/libc-2.16.so
7ffff7682000-7ffff7686000 rw-p 00000000 00:00 0 
7ffff7686000-7ffff7698000 r-xp 00000000 08:01 289536                     /usr/lib/libmpdclient.so.2.0.5
7ffff7698000-7ffff7898000 ---p 00012000 08:01 289536                     /usr/lib/libmpdclient.so.2.0.5
7ffff7898000-7ffff7899000 r--p 00012000 08:01 289536                     /usr/lib/libmpdclient.so.2.0.5
7ffff7899000-7ffff789a000 rw-p 00013000 08:01 289536                     /usr/lib/libmpdclient.so.2.0.5
7ffff789a000-7ffff78a2000 r-xp 00000000 08:01 278692                     /usr/lib/libiw.so.29
7ffff78a2000-7ffff7aa1000 ---p 00008000 08:01 278692                     /usr/lib/libiw.so.29
7ffff7aa1000-7ffff7aa2000 rw-p 00007000 08:01 278692                     /usr/lib/libiw.so.29
7ffff7aa2000-7ffff7bd5000 r-xp 00000000 08:01 281434                     /usr/lib/libX11.so.6.3.0
7ffff7bd5000-7ffff7dd5000 ---p 00133000 08:01 281434                     /usr/lib/libX11.so.6.3.0
7ffff7dd5000-7ffff7dd6000 r--p 00133000 08:01 281434                     /usr/lib/libX11.so.6.3.0
7ffff7dd6000-7ffff7ddb000 rw-p 00134000 08:01 281434                     /usr/lib/libX11.so.6.3.0
7ffff7ddb000-7ffff7dfc000 r-xp 00000000 08:01 263930                     /usr/lib/ld-2.16.so
7ffff7fd8000-7ffff7fdd000 rw-p 00000000 00:00 0 
7ffff7ffa000-7ffff7ffb000 rw-p 00000000 00:00 0 
7ffff7ffb000-7ffff7ffc000 r-xp 00000000 00:00 0                          [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00021000 08:01 263930                     /usr/lib/ld-2.16.so
7ffff7ffd000-7ffff7ffe000 rw-p 00022000 08:01 263930                     /usr/lib/ld-2.16.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0 
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0                          [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

Program received signal SIGABRT, Aborted.
0x00007ffff7313fa5 in raise () from /usr/lib/libc.so.6

Note that this is without the MPD part, that still segfaults tongue

Last edited by Unia (2012-09-15 10:13:27)


If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

#23 2012-09-15 11:18:28

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,441
Website

Re: [SOLVED] A DWM statusbar in C

Well this error is easy.  It says it's a double free.  You call "free" on a pointer more than once.  This is because you allocate space for winfo (malloc) before the loop starts.  In the loop you free(winfo).  winfo is never reallocated, but the second time through the loop you free it again.

I don't know the iwlib functions yet, but I suspect that instead of free(winfo) you should use memset on winfo instead to zero it out.  If the iwlib function allocates space for winfo->b, then you'll have to free winfo->b, but not winfo itself.

Looking at moetunes' code indicates that you should malloc the winfo structure before the loop, and only free it after the loop closes.  At the start of each iteration through the wireless section of the loop you should just use memset to zero it out.

(NOTE: if this adds confusion consider the next paragraph as a suggestion for future consideration.  This will not affect whether the app will "work", but once functioning well, this would be good to consider to ensure it behaves nicely.)
Further, though, in this situation you do not need to declare winfo as a pointer and allocate space for it, I'd suggest declaring it "normally".  From your perspective the only difference would be that all the "winfo->b" or "winfo->some_variable" would have to change to "winfo.b" or "winfo.some_variable".  The advantage would be that as dwmStatus really will never exit normally, that free statment after the loop would never actually execute.  This could potentially mean that this memory space will never be released back to the system (though I think the OS is smarter than this).  In the case of a normally declared variable, the garbage collector should release all declared variables no matter how the program exists (AFAIK).  In other words, while the garbage collection details are a bit outside my expertise, declaring such a variable locally rather than as a malloc'ed pointer can only help ensure the memory will be released when the program ends.

-------

Edit: there are a few different ways of having that only run every minute.  In this case I think the best would be to put the whole wireless block of code inside an if statement as follows

int main() {
  int loops=0;
  ...
  for(;;) {
    ...
    if (++loops == 60) { /* 60 here assumes that each loop sleeps for 1 second and you want to check wireless every minute.  Adjust as needed */
      loops=0;
      /*wifi stuff here*/
    }
    ...
  }
  ...
}

Last edited by Trilby (2012-09-15 20:21:09)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#24 2012-09-15 12:00:10

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,441
Website

Re: [SOLVED] A DWM statusbar in C

Unia, I've been looking at the MPD section, but I can't find any documentation for the mpd api - do you have any links?

A couple things jump out at me.  First I don't think your variable "i" is doing what you think it is doing.  Every time through the loop you end up calling:

artist = mpd_song_get_tag(song,MPD_TAG_ARTIST,1);
title = mpd_song_get_tag(song,MPD_TAG_TITLE,0);

I don't know what the last argument to those functions should be, but this is what they end up being every time - so there is really no point in using a variable for that.  I suspect you had a reason for using the variable, but it ends up not doing what you intended.

More importantly your artist and title variables have a couple problems.  First, you declare them as const, but then you try to set them.  The compiler should warn you about this, or give an error for it.  Second, either you have to allocate space for the strings, or if mp_song_get_tag allocates the space for them, you'll have to free it each time through the loop.

EDIT: there's also something off about the while loop - but without the documentation for mpd I'm not sure which part to point out.  I assume the function in the while conditional sets the "conn" variable, but if this is the case you should use the mpd_connection_free(conn) at the end of each iteration through the while loop, not after the while loop.  As it stands, if the conditional statement of the while loop sets conn, on the second iteration through the while loop that statement will try to reset conn before it has been freed.  Further I'm not really sure what the purpose of the while loop is in general, you're not playing more than one song at once right?  Should that while be an if??

Last edited by Trilby (2012-09-15 12:09:32)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#25 2012-09-15 15:25:44

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

Re: [SOLVED] A DWM statusbar in C

Trilby wrote:

Well this error is easy.  It says it's a double free.  You call "free" on a pointer more than once.  This is because you allocate space for winfo (malloc) before the loop starts.  In the loop you free(winfo).  winfo is never reallocated, but the second time through the loop you free it again.

I don't know the iwlib functions yet, but I suspect that instead of free(winfo) you should use memset on winfo instead to zero it out.  If the iwlib function allocates space for winfo->b, then you'll have to free winfo->b, but not winfo itself.

Looking at moetunes' code indicates that you should malloc the winfo structure before the loop, and only free it after the loop closes.  At the start of each iteration through the wireless section of the loop you should just use memset to zero it out.

Using memset indeed does the trick! Although, the code you suggested to have it updated once a minute, doesn't work - it doesn't show anything at all when I use that. I'm not sure if I'm going to use the percentage at all, maybe I'll just make the ESSID go red (urgent) when signal < 40% or something. I don't care for the signal that much; just want to know if it's good or bad.

I'll look into the MPD part now. I don't know any of the API. I just glued this together from a statusbar in C I found online (EDIT: Found it: http://sprunge.us/jZfc) and the code I have from my mpd-notify.

Last edited by Unia (2012-09-15 16:26:33)


If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

Board footer

Powered by FluxBB