VirtualBox

source: vbox/trunk/src/VBox/ExtPacks/VBoxDTrace/VBoxDTraceWrapper.cpp@ 69496

Last change on this file since 69496 was 69496, checked in by vboxsync, 7 years ago

*: scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.8 KB
Line 
1/* $Id: VBoxDTraceWrapper.cpp 69496 2017-10-28 14:55:58Z vboxsync $ */
2/** @file
3 * VBoxDTrace - Wrapper that selects the right dtrace implemetation and adds
4 * our library to the search path.
5 */
6
7/*
8 * Copyright (C) 2016-2017 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the Common
13 * Development and Distribution License Version 1.0 (CDDL) only, as it
14 * comes in the "COPYING.CDDL" file of the VirtualBox OSE distribution.
15 * VirtualBox OSE is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY of any kind.
17 */
18
19
20/*********************************************************************************************************************************
21* Header Files *
22*********************************************************************************************************************************/
23#include <iprt/buildconfig.h>
24#include <iprt/env.h>
25#include <iprt/file.h>
26#include <iprt/initterm.h>
27#include <iprt/ldr.h>
28#include <iprt/message.h>
29#include <iprt/path.h>
30#include <iprt/process.h>
31#include <iprt/string.h>
32
33#include <VBox/sup.h>
34
35#include "../../Main/include/ExtPackUtil.h"
36
37
38/*********************************************************************************************************************************
39* Defined Constants And Macros *
40*********************************************************************************************************************************/
41/** The VBoxDTrace extension pack name. */
42#define VBOX_EXTPACK_VBOXDTRACE_NAME "Oracle VBoxDTrace Extension Pack"
43/** The mangled version of VBOX_EXTPACK_VBOXDTRACE_NAME (also in Config.kmk). */
44#define VBOX_EXTPACK_VBOXDTRACE_MANGLED_NAME "Oracle_VBoxDTrace_Extension_Pack"
45
46
47/*********************************************************************************************************************************
48* Structures and Typedefs *
49*********************************************************************************************************************************/
50/** The main function of VBoxDTrace.so/dylib/dll. */
51typedef int (RTCALL *PFNVBOXDTRACEMAIN)(int argc, char **argv);
52
53
54int main(int argc, char **argv)
55{
56 /*
57 * Init IPRT.
58 */
59 int rc = RTR3InitExe(argc, &argv, 0);
60 if (RT_FAILURE(rc))
61 return RTMsgInitFailure(rc);
62
63 /*
64 * Locate a native DTrace command binary.
65 */
66 bool fIsNativeDTrace = false;
67 char szDTraceCmd[RTPATH_MAX];
68 szDTraceCmd[0] = '\0';
69
70#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) || defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS)
71 /*
72 * 1. Try native first on platforms where it's applicable.
73 */
74 static const char * const s_apszNativeDTrace[] =
75 {
76 "/usr/sbin/dtrace",
77 "/sbin/dtrace",
78 "/usr/bin/dtrace",
79 "/bin/dtrace",
80 "/usr/local/sbin/dtrace",
81 "/usr/local/bin/dtrace"
82 };
83 if (!RTEnvExist("VBOX_DTRACE_NO_NATIVE"))
84 for (uint32_t i = 0; i < RT_ELEMENTS(s_apszNativeDTrace); i++)
85 if (RTFileExists(s_apszNativeDTrace[i]))
86 {
87 fIsNativeDTrace = true;
88 strcpy(szDTraceCmd, s_apszNativeDTrace[i]);
89# ifdef RT_OS_LINUX
90 /** @todo Warn if the dtrace modules haven't been loaded or vboxdrv isn't
91 * compiled against them. */
92# endif
93 break;
94 }
95 if (szDTraceCmd[0] == '\0')
96#endif
97 {
98 /*
99 * 2. VBoxDTrace extension pack installed?
100 *
101 * Note! We cannot use the COM API here because this program is usually
102 * run thru sudo or directly as root, even if the target
103 * VirtualBox process is running as regular user. This is due to
104 * the privileges required to run dtrace scripts on a host.
105 */
106 rc = RTPathAppPrivateArch(szDTraceCmd, sizeof(szDTraceCmd));
107 if (RT_SUCCESS(rc))
108 rc = RTPathAppend(szDTraceCmd, sizeof(szDTraceCmd),
109 VBOX_EXTPACK_INSTALL_DIR RTPATH_SLASH_STR VBOX_EXTPACK_VBOXDTRACE_MANGLED_NAME);
110 if (RT_SUCCESS(rc))
111 rc = RTPathAppend(szDTraceCmd, sizeof(szDTraceCmd), RTBldCfgTargetDotArch());
112 if (RT_SUCCESS(rc))
113 rc = RTPathAppend(szDTraceCmd, sizeof(szDTraceCmd), "VBoxDTraceCmd");
114 if (RT_SUCCESS(rc))
115 rc = RTStrCat(szDTraceCmd, sizeof(szDTraceCmd), RTLdrGetSuff());
116 if (RT_FAILURE(rc))
117 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error constructing extension pack path: %Rrc", rc);
118 if (!RTFileExists(szDTraceCmd))
119 return RTMsgErrorExit(RTEXITCODE_FAILURE,
120 "Unable to find a DTrace implementation. VBoxDTrace Extension Pack installed?");
121 fIsNativeDTrace = false;
122 }
123
124
125 /*
126 * Construct a new command line that includes our libary.
127 */
128 char szDTraceLibDir[RTPATH_MAX];
129 rc = RTPathAppPrivateNoArch(szDTraceLibDir, sizeof(szDTraceLibDir));
130 if (RT_SUCCESS(rc))
131 rc = RTPathAppend(szDTraceLibDir, sizeof(szDTraceLibDir), "dtrace" RTPATH_SLASH_STR "lib");
132 if (RT_SUCCESS(rc))
133 rc = RTPathAppend(szDTraceLibDir, sizeof(szDTraceLibDir), RTBldCfgTargetArch());
134 if (RT_FAILURE(rc))
135 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error constructing dtrace library path for VBox: %Rrc", rc);
136
137 char **papszArgs = (char **)RTMemAlloc((argc + 3) * sizeof(char *));
138 if (!papszArgs)
139 return RTMsgErrorExit(RTEXITCODE_FAILURE, "No memory for argument list.");
140
141 int cArgs = 1;
142 papszArgs[0] = fIsNativeDTrace ? szDTraceCmd : argv[0];
143 if (argc > 1)
144 {
145 papszArgs[cArgs++] = (char *)"-L";
146 papszArgs[cArgs++] = szDTraceLibDir;
147 }
148 for (int i = 1; i < argc; i++)
149 papszArgs[cArgs++] = argv[i];
150 papszArgs[cArgs] = NULL;
151 Assert(cArgs <= argc + 3);
152
153
154 /*
155 * The native DTrace we execute as a sub-process and wait for.
156 */
157 RTEXITCODE rcExit;
158 if (fIsNativeDTrace)
159 {
160 RTPROCESS hProc;
161 rc = RTProcCreate(szDTraceCmd, papszArgs, RTENV_DEFAULT, 0, &hProc);
162 if (RT_SUCCESS(rc))
163 {
164 RTPROCSTATUS Status;
165 rc = RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &Status);
166 if (RT_SUCCESS(rc))
167 {
168 if (Status.enmReason == RTPROCEXITREASON_NORMAL)
169 rcExit = (RTEXITCODE)Status.iStatus;
170 else
171 rcExit = RTEXITCODE_FAILURE;
172 }
173 else
174 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Error waiting for child process: %Rrc", rc);
175 }
176 else
177 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Error executing '%s': %Rrc", szDTraceCmd, rc);
178 }
179 /*
180 * While the VBoxDTrace we load and call the main function of.
181 */
182 else
183 {
184 RTERRINFOSTATIC ErrInfo;
185 RTLDRMOD hMod;
186 rc = SUPR3HardenedLdrLoadPlugIn(szDTraceCmd, &hMod, RTErrInfoInitStatic(&ErrInfo));
187 if (RT_SUCCESS(rc))
188 {
189 PFNVBOXDTRACEMAIN pfnVBoxDTraceMain;
190 rc = RTLdrGetSymbol(hMod, "VBoxDTraceMain", (void **)&pfnVBoxDTraceMain);
191 if (RT_SUCCESS(rc))
192 rcExit = (RTEXITCODE)pfnVBoxDTraceMain(cArgs, papszArgs);
193 else
194 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Error locating 'VBoxDTraceMain' in '%s': %Rrc", szDTraceCmd, rc);
195 }
196 else
197 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Error loading '%s': %Rrc (%s)", szDTraceCmd, rc, ErrInfo.szMsg);
198 }
199 return rcExit;
200}
201
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette