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