14fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// Copyright (c) 2012, Google Inc. 24fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// All rights reserved. 34fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// 44fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// Redistribution and use in source and binary forms, with or without 54fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// modification, are permitted provided that the following conditions are 64fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// met: 74fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// 84fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// * Redistributions of source code must retain the above copyright 94fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// notice, this list of conditions and the following disclaimer. 104fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// * Redistributions in binary form must reproduce the above 114fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// copyright notice, this list of conditions and the following disclaimer 124fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// in the documentation and/or other materials provided with the 134fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// distribution. 144fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// * Neither the name of Google Inc. nor the names of its 154fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// contributors may be used to endorse or promote products derived from 164fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// this software without specific prior written permission. 174fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// 184fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 194fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 204fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 214fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 224fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 234fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 244fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 254fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 264fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 274fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 284fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 294fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 304fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// linux_core_dumper_unittest.cc: 314fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// Unit tests for google_breakpad::LinuxCoreDumoer. 324fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 334e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com#include <string> 344e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com 354fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org#include "breakpad_googletest_includes.h" 364fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org#include "client/linux/minidump_writer/linux_core_dumper.h" 374fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org#include "common/linux/tests/crash_generator.h" 384e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com#include "common/using_std_string.h" 394fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 404fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.orgusing namespace google_breakpad; 414fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 424fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.orgTEST(LinuxCoreDumperTest, BuildProcPath) { 434fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org const pid_t pid = getpid(); 444fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org const char procfs_path[] = "/procfs_copy"; 454fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org LinuxCoreDumper dumper(getpid(), "core_file", procfs_path); 464fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 474fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org char maps_path[NAME_MAX] = ""; 484fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org char maps_path_expected[NAME_MAX]; 494fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org snprintf(maps_path_expected, sizeof(maps_path_expected), 504fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org "%s/maps", procfs_path); 514fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org EXPECT_TRUE(dumper.BuildProcPath(maps_path, pid, "maps")); 524fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org EXPECT_STREQ(maps_path_expected, maps_path); 534fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 544fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org EXPECT_FALSE(dumper.BuildProcPath(NULL, pid, "maps")); 554fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org EXPECT_FALSE(dumper.BuildProcPath(maps_path, pid, "")); 564fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org EXPECT_FALSE(dumper.BuildProcPath(maps_path, pid, NULL)); 574fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 584fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org char long_node[NAME_MAX]; 594fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org size_t long_node_len = NAME_MAX - strlen(procfs_path) - 1; 604fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org memset(long_node, 'a', long_node_len); 614fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org long_node[long_node_len] = '\0'; 624fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org EXPECT_FALSE(dumper.BuildProcPath(maps_path, pid, long_node)); 634fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org} 644fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 654fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.orgTEST(LinuxCoreDumperTest, VerifyDumpWithMultipleThreads) { 664fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org CrashGenerator crash_generator; 674fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org if (!crash_generator.HasDefaultCorePattern()) { 6813de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org fprintf(stderr, "LinuxCoreDumperTest.VerifyDumpWithMultipleThreads test " 694fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org "is skipped due to non-default core pattern\n"); 704fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org return; 714fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org } 724fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 734fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org const unsigned kNumOfThreads = 3; 744fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org const unsigned kCrashThread = 1; 754fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org const int kCrashSignal = SIGABRT; 764fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org pid_t child_pid; 77548501df371a517683d8b4d05c05b3929ad43141vapier@chromium.org ASSERT_TRUE(crash_generator.CreateChildCrash(kNumOfThreads, kCrashThread, 78548501df371a517683d8b4d05c05b3929ad43141vapier@chromium.org kCrashSignal, &child_pid)); 794fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 8013de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org const string core_file = crash_generator.GetCoreFilePath(); 8113de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org const string procfs_path = crash_generator.GetDirectoryOfProcFilesCopy(); 82850b8dc0f0ddab5c042ac61fecbbf493fac3c66brmcilroy@chromium.org 83850b8dc0f0ddab5c042ac61fecbbf493fac3c66brmcilroy@chromium.org#if defined(__ANDROID__) 84850b8dc0f0ddab5c042ac61fecbbf493fac3c66brmcilroy@chromium.org struct stat st; 85850b8dc0f0ddab5c042ac61fecbbf493fac3c66brmcilroy@chromium.org if (stat(core_file.c_str(), &st) != 0) { 86850b8dc0f0ddab5c042ac61fecbbf493fac3c66brmcilroy@chromium.org fprintf(stderr, "LinuxCoreDumperTest.VerifyDumpWithMultipleThreads test is " 87850b8dc0f0ddab5c042ac61fecbbf493fac3c66brmcilroy@chromium.org "skipped due to no core file being generated"); 88850b8dc0f0ddab5c042ac61fecbbf493fac3c66brmcilroy@chromium.org return; 89850b8dc0f0ddab5c042ac61fecbbf493fac3c66brmcilroy@chromium.org } 90850b8dc0f0ddab5c042ac61fecbbf493fac3c66brmcilroy@chromium.org#endif 91850b8dc0f0ddab5c042ac61fecbbf493fac3c66brmcilroy@chromium.org 9213de24a86ecf4d87d9c151e496282123c4654958benchan@chromium.org LinuxCoreDumper dumper(child_pid, core_file.c_str(), procfs_path.c_str()); 93850b8dc0f0ddab5c042ac61fecbbf493fac3c66brmcilroy@chromium.org 94b732342313268422c0c0794dfb1a82cd17ce9e05ivan.penkov@gmail.com EXPECT_TRUE(dumper.Init()); 954fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 964fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org EXPECT_TRUE(dumper.IsPostMortem()); 974fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 984fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // These are no-ops and should always return true. 994fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org EXPECT_TRUE(dumper.ThreadsSuspend()); 1004fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org EXPECT_TRUE(dumper.ThreadsResume()); 1014fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 1024fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // LinuxCoreDumper cannot determine the crash address and thus it always 1034fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // sets the crash address to 0. 1042971a050754f48aaa807db47a29e0d0beddbdcf7ivan.penkov@gmail.com EXPECT_EQ(0U, dumper.crash_address()); 1054fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org EXPECT_EQ(kCrashSignal, dumper.crash_signal()); 1064fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org EXPECT_EQ(crash_generator.GetThreadId(kCrashThread), 1074fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org dumper.crash_thread()); 1084fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 1094fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org EXPECT_EQ(kNumOfThreads, dumper.threads().size()); 1104fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org for (unsigned i = 0; i < kNumOfThreads; ++i) { 1114fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org ThreadInfo info; 1124fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org EXPECT_TRUE(dumper.GetThreadInfoByIndex(i, &info)); 113a576a63122315d8675b8ef6b43c848e627354afbmkrebs@chromium.org const void* stack; 114a576a63122315d8675b8ef6b43c848e627354afbmkrebs@chromium.org size_t stack_len; 115a576a63122315d8675b8ef6b43c848e627354afbmkrebs@chromium.org EXPECT_TRUE(dumper.GetStackInfo(&stack, &stack_len, info.stack_pointer)); 1164fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org EXPECT_EQ(getpid(), info.ppid); 1174fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org } 1184fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org} 119