From 74d5c1e499d87b5d16562ab3e6ae398ed3b2e386 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Wed, 9 Jul 2008 03:58:38 +0000 Subject: [PATCH] * Fixed serious memory leak in team_create_thread_start(). The destructor of the automatic KPath variable was never invoked, since normally arch_thread_enter_userspace() would not return and thus the function scope never be left. After a standard "jam @image" almost 42 MB of kernel heap were lost this way. * Added a few warning comments in functions that shouldn't use automatic variables with a destructor in the function scope either. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26336 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/team.cpp | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp index 102904f515..3f7de5f00a 100644 --- a/src/system/kernel/team.cpp +++ b/src/system/kernel/team.cpp @@ -1041,20 +1041,25 @@ team_create_thread_start(void *args) // the arguments are already on the user stack, we no longer need // them in this form - // find runtime_loader path - KPath runtimeLoaderPath; - err = find_directory(B_BEOS_SYSTEM_DIRECTORY, gBootDevice, false, - runtimeLoaderPath.LockBuffer(), runtimeLoaderPath.BufferSize()); - if (err < B_OK) { - TRACE(("team_create_thread_start: find_directory() failed: %s\n", - strerror(err))); - return err; - } - runtimeLoaderPath.UnlockBuffer(); - err = runtimeLoaderPath.Append("runtime_loader"); + // NOTE: Normally arch_thread_enter_userspace() never returns, that is + // automatic variables with function scope will never be destroyed. + { + // find runtime_loader path + KPath runtimeLoaderPath; + err = find_directory(B_BEOS_SYSTEM_DIRECTORY, gBootDevice, false, + runtimeLoaderPath.LockBuffer(), runtimeLoaderPath.BufferSize()); + if (err < B_OK) { + TRACE(("team_create_thread_start: find_directory() failed: %s\n", + strerror(err))); + return err; + } + runtimeLoaderPath.UnlockBuffer(); + err = runtimeLoaderPath.Append("runtime_loader"); + + if (err == B_OK) + err = elf_load_user_image(runtimeLoaderPath.Path(), team, 0, &entry); + } - if (err == B_OK) - err = elf_load_user_image(runtimeLoaderPath.Path(), team, 0, &entry); if (err < B_OK) { // Luckily, we don't have to clean up the mess we created - that's // done for us by the normal team deletion process @@ -1247,6 +1252,8 @@ static status_t exec_team(const char *path, char**& _flatArgs, size_t flatArgsSize, int32 argCount, int32 envCount) { + // NOTE: Since this function normally doesn't return, don't use automatic + // variables that need destruction in the function scope. char** flatArgs = _flatArgs; struct team *team = thread_get_current_thread()->team; struct team_arg *teamArgs; @@ -2949,6 +2956,8 @@ status_t _user_exec(const char *userPath, const char* const* userFlatArgs, size_t flatArgsSize, int32 argCount, int32 envCount) { + // NOTE: Since this function normally doesn't return, don't use automatic + // variables that need destruction in the function scope. char path[B_PATH_NAME_LENGTH]; if (!IS_USER_ADDRESS(userPath) || !IS_USER_ADDRESS(userFlatArgs)