When an application is created with WMInitializeApplication,
it's never destroyed properly.
The patch is adding some functions to free the memory and taking as
example 'wmsetbg'.
Moreover, in wmsetbg.c I also corrected 2 compiler warnings and a
possible buffer overflow.

Next step is to track down other WMInitializeApplication calls.
Below are the valgrind reports.

###########################################################
before:

# valgrind wmsetbg
==9646== Memcheck, a memory error detector
==9646== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==9646== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==9646== Command: wmsetbg
==9646==
wmsetbg: you must specify a image file name or a texture
Try 'wmsetbg --help' for more information
==9646==
==9646== HEAP SUMMARY:
==9646==     in use at exit: 760 bytes in 10 blocks
==9646==   total heap usage: 38 allocs, 28 frees, 4,397 bytes allocated
==9646==
==9646== LEAK SUMMARY:
==9646==    definitely lost: 0 bytes in 0 blocks
==9646==    indirectly lost: 0 bytes in 0 blocks
==9646==      possibly lost: 0 bytes in 0 blocks
==9646==    still reachable: 760 bytes in 10 blocks
==9646==         suppressed: 0 bytes in 0 blocks
==9646== Rerun with --leak-check=full to see details of leaked memory



###########################################################
after:

# valgrind wmsetbg
==10670== Memcheck, a memory error detector
==10670== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==10670== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==10670== Command: wmsetbg
==10670==

wmsetbg: you must specify a image file name or a texture
Try 'wmsetbg --help' for more information
==10670==
==10670== HEAP SUMMARY:
==10670==     in use at exit: 0 bytes in 0 blocks
==10670==   total heap usage: 38 allocs, 38 frees, 4,397 bytes allocated
==10670==
==10670== All heap blocks were freed -- no leaks are possible


Patch is below and enclosed.

---
 WINGs/WINGs/WINGs.h       |  3 ++-
 WINGs/notification.c      | 12 +++++++++++
 WINGs/wapplication.c      | 11 ++++++++++
 WPrefs.app/TexturePanel.c |  1 +
 util/wmsetbg.c            | 54 ++++++++++++++++++++++++++++-------------------
 5 files changed, 58 insertions(+), 23 deletions(-)

diff --git a/WINGs/WINGs/WINGs.h b/WINGs/WINGs/WINGs.h
index aa95844..6597504 100644
--- a/WINGs/WINGs/WINGs.h
+++ b/WINGs/WINGs/WINGs.h
@@ -642,9 +642,10 @@ WMRect wmkrect(int x, int y, unsigned int width,
unsigned int height);
 /* ---[ WINGs/wapplication.c ]-------------------------------------------- */


-
 void WMInitializeApplication(const char *applicationName, int *argc,
char **argv);

+void WMReleaseApplication();
+
 void WMSetResourcePath(const char *path);

 /* don't free the returned string */
diff --git a/WINGs/notification.c b/WINGs/notification.c
index ada942f..ebb05ec 100644
--- a/WINGs/notification.c
+++ b/WINGs/notification.c
@@ -94,6 +94,18 @@ void W_InitNotificationCenter(void)
  notificationCenter->observerTable = WMCreateHashTable(WMIntHashCallbacks);
 }

+void WMReleaseNotificationCenter()
+{
+ if (notificationCenter->nameTable)
+ WMFreeHashTable(notificationCenter->nameTable);
+ if (notificationCenter->objectTable)
+ WMFreeHashTable(notificationCenter->objectTable);
+ if (notificationCenter->observerTable)
+ WMFreeHashTable(notificationCenter->observerTable);
+ if (notificationCenter)
+ wfree(notificationCenter);
+}
+
 void
 WMAddNotificationObserver(WMNotificationObserverAction * observerAction,
   void *observer, const char *name, void *object)
diff --git a/WINGs/wapplication.c b/WINGs/wapplication.c
index a0aec2e..84ede06 100644
--- a/WINGs/wapplication.c
+++ b/WINGs/wapplication.c
@@ -48,6 +48,17 @@ void WMInitializeApplication(const char
*applicationName, int *argc, char **argv
  W_InitNotificationCenter();
 }

+void WMReleaseApplication() {
+ int i =0;
+ if (WMApplication.applicationName)
+ wfree(WMApplication.applicationName);
+ for (i = 0; i < WMApplication.argc; i++)
+ wfree(WMApplication.argv[i]);
+ if (WMApplication.argv)
+ wfree(WMApplication.argv);
+ WMReleaseNotificationCenter();
+}
+
 void WMSetResourcePath(const char *path)
 {
  if (WMApplication.resourcePath)
diff --git a/WPrefs.app/TexturePanel.c b/WPrefs.app/TexturePanel.c
index 9f2b86a..530c124 100644
--- a/WPrefs.app/TexturePanel.c
+++ b/WPrefs.app/TexturePanel.c
@@ -1527,6 +1527,7 @@ int main(int argc, char **argv)
  ShowTexturePanel(panel);

  WMScreenMainLoop(scr);
+ WMReleaseApplication();
  return 0;
 }
 #endif
diff --git a/util/wmsetbg.c b/util/wmsetbg.c
index 644c85d..d85eb43 100644
--- a/util/wmsetbg.c
+++ b/util/wmsetbg.c
@@ -100,6 +100,12 @@ typedef struct BackgroundTexture {
  int height;
 } BackgroundTexture;

+static void quit(int rcode)
+{
+ WMReleaseApplication();
+ exit(rcode);
+}
+
 static void initXinerama(void)
 {
  xineInfo.screens = NULL;
@@ -903,7 +909,7 @@ static noreturn void helperLoop(RContext * rc)
  errcount--;
  if (errcount == 0) {
  wfatal("quitting");
- exit(1);
+ quit(1);
  }
  continue;
  }
@@ -917,7 +923,7 @@ static noreturn void helperLoop(RContext * rc)
  errcount--;
  if (errcount == 0) {
  wfatal("quitting");
- exit(1);
+ quit(1);
  }
  continue;
  }
@@ -973,7 +979,7 @@ static noreturn void helperLoop(RContext * rc)
 #ifdef DEBUG
  printf("exit command\n");
 #endif
- exit(0);
+ quit(0);

  default:
  wwarning("unknown message received");
@@ -987,9 +993,11 @@ static void updateDomain(const char *domain,
const char *key, const char *textur
  char *program = "wdwrite";

  /* here is a mem leak */
- system(wstrconcat("wdwrite ",
+ int result = system(wstrconcat("wdwrite ",
   wstrconcat(domain, smooth ? " SmoothWorkspaceBack YES" : "
SmoothWorkspaceBack NO")));

+ if (result == -1)
+ werror("error executing system command");
  execlp(program, program, domain, key, texture, NULL);
  wwarning("warning could not run \"%s\"", program);
 }
@@ -1228,7 +1236,7 @@ int main(int argc, char **argv)
  i++;
  if (i >= argc) {
  wfatal("too few arguments for %s", argv[i - 1]);
- exit(1);
+ quit(1);
  }
  display = argv[i];
  } else if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--scale") == 0) {
@@ -1260,61 +1268,61 @@ int main(int argc, char **argv)
  i++;
  if (i >= argc) {
  wfatal("too few arguments for %s", argv[i - 1]);
- exit(1);
+ quit(1);
  }
  domain = wstrdup(argv[i]);
  } else if (strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--colors") == 0) {
  i++;
  if (i >= argc) {
  wfatal("too few arguments for %s", argv[i - 1]);
- exit(1);
+ quit(1);
  }
  if (sscanf(argv[i], "%i", &cpc) != 1) {
  wfatal("bad value for colors per channel: \"%s\"", argv[i]);
- exit(1);
+ quit(1);
  }
  } else if (strcmp(argv[i], "-b") == 0 || strcmp(argv[i],
"--back-color") == 0) {
  i++;
  if (i >= argc) {
  wfatal("too few arguments for %s", argv[i - 1]);
- exit(1);
+ quit(1);
  }
  back_color = argv[i];
  } else if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "--parse") == 0) {
  i++;
  if (i >= argc) {
  wfatal("too few arguments for %s", argv[i - 1]);
- exit(1);
+ quit(1);
  }
  texture = argv[i];
  } else if (strcmp(argv[i], "-w") == 0 || strcmp(argv[i],
"--workspace") == 0) {
  i++;
  if (i >= argc) {
  wfatal("too few arguments for %s", argv[i - 1]);
- exit(1);
+ quit(1);
  }
  if (sscanf(argv[i], "%i", &workspace) != 1) {
  wfatal("bad value for workspace number: \"%s\"", argv[i]);
- exit(1);
+ quit(1);
  }
  } else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) {
  printf("%s (Window Maker %s)\n", __progname, VERSION);
- exit(0);
+ quit(0);
  } else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
  print_help();
- exit(0);
+ quit(0);
  } else if (argv[i][0] != '-') {
  image_name = argv[i];
  } else {
  printf("%s: invalid argument '%s'\n", __progname, argv[i]);
  printf("Try '%s --help' for more information\n", __progname);
- exit(1);
+ quit(1);
  }
  }
  if (!image_name && !texture && !helperMode) {
  printf("%s: you must specify a image file name or a texture\n", __progname);
  printf("Try '%s --help' for more information\n", __progname);
- exit(1);
+ quit(1);
  }

  PixmapPath = getPixmapPath(domain);
@@ -1334,7 +1342,7 @@ int main(int argc, char **argv)
  dpy = XOpenDisplay(display);
  if (!dpy) {
  wfatal("could not open display");
- exit(1);
+ quit(1);
  }
 #if 0
  XSynchronize(dpy, 1);
@@ -1367,12 +1375,14 @@ int main(int argc, char **argv)

  if (!rc) {
  wfatal("could not initialize wrlib: %s", RMessageForError(RErrorCode));
- exit(1);
+ quit(1);
  }

  if (helperMode) {
  /* lower priority, so that it wont use all the CPU */
- nice(15);
+ int result = nice(15);
+ if (result == -1)
+ werror("error could not nice process");

  helperLoop(rc);
  } else {
@@ -1381,8 +1391,7 @@ int main(int argc, char **argv)

  if (!texture) {
  char *image_path = getFullPixmapPath(image_name);
-
- sprintf(buffer, "(%s, \"%s\", %s)", style, image_path, back_color);
+ snprintf(buffer, sizeof(buffer), "(%s, \"%s\", %s)", style,
image_path, back_color);
  wfree(image_path);
  texture = (char *)buffer;
  }
@@ -1393,7 +1402,7 @@ int main(int argc, char **argv)

  tex = parseTexture(rc, texture);
  if (!tex)
- exit(1);
+ quit(1);

  if (workspace < 0)
  changeTexture(tex);
@@ -1403,5 +1412,6 @@ int main(int argc, char **argv)
  }
  }

+ WMReleaseApplication();
  return 0;
 }
-- 
1.8.3.2

Attachment: 0001-Cleaned releasing application.patch
Description: Binary data

Reply via email to