HPCToolkit
monitor_static.cpp
Go to the documentation of this file.
1 // -*-Mode: C++;-*-
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL$
6 // $Id$
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2019, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 /****************************************************************************
48 //
49 // File:
50 // $HeadURL$
51 //
52 // Purpose:
53 // Implements monitoring for any application (including statically
54 // linked), launched by linking this library into one's
55 // application. The library starts and stops monitoring.
56 //
57 // Description:
58 // [The set of functions, macros, etc. defined in the file]
59 //
60 // Author:
61 // Written by John Mellor-Crummey and Nathan Tallent, Rice University.
62 //
63 *****************************************************************************/
64 
65 #define USE_STATIC_CONSTRUCTOR 1
66 
67 /************************** System Include Files ****************************/
68 
69 #include <stdlib.h>
70 #include <errno.h>
71 /* #include <pthread.h> */
72 
73 #include <dlfcn.h>
74 
75 /**************************** User Include Files ****************************/
76 
77 #include "monitor.h"
78 #include "hpcrun.h"
79 #include "rtmap.h"
80 
81 /**************************** Forward Declarations **************************/
82 
83 /*
84  For profiling of statically linked apps:
85 
86  - User must relink application, placing libhpcrun-static.o after
87  all user code libraries/objects but before either libpthread or
88  libc.
89 
90  - We can launch the application with hpcrun. This will set the
91  environment (and also set the unnecessary LD_* vars, but who
92  cares?)
93  - We will have to change hpcrun to be linked with papi. It will
94  not work to be dynamically link on a statically linked platform.
95 
96  - We can initialize profiling with a C++ static constructor
97  - We should also be able to 'intercept' __libc_start_main
98 
99  - Similarly, we should be able to intercept thread creation,
100  forks, etc:
101  - use special bogus names for the definition of the routines we
102  want to intercept, but use the real names when calling the
103  intercepted routines
104  - link in the real routines: pre-link our lib against libc or
105  libpthreads
106  - hide the real routines
107  - rename our entry points to the real names *so they are found
108  on the link line)
109 */
110 
111 
112 /****************************************************************************
113  * Library initialization and finalization
114  ****************************************************************************/
115 
116 #if USE_STATIC_CONSTRUCTOR
117 
118 /*
119  * C++ Static constructor/deconstructor: (FIXME)
120  */
121 class Launcher {
122 public:
123  Launcher() {
124  /* initialize */
125  init_library();
126  init_process();
127  }
129  /* finalize */
130  fini_process();
131  fini_library();
132  }
133 };
134 
136 
137 #endif
138 
139 
140 /*
141  * Library initialization
142  */
143 extern void
145 {
146 #if USE_STATIC_CONSTRUCTOR
148 
149  if (opt_debug >= 1) {
150  MSG(stderr, "*** launching intercepted app: %s ***", hpcrun_cmd);
151  }
152 #endif
153 }
154 
155 
156 /****************************************************************************
157  * Intercepted routines
158  ****************************************************************************/
159 
160 #if !USE_STATIC_CONSTRUCTOR
161 
162 // FIXME: do not need real_libc_start_main as extern
163 
164 // __libc_start_main __BP___libc_start_main
165 // execv execvp execve
166 // pthread_create pthread_self
167 
168 /*
169  * Intercept the start routine: this is from glibc and can be one of
170  * two different names depending on how the macro BP_SYM is defined.
171  * glibc-x/sysdeps/generic/libc-start.c
172  */
173 extern int
174 HPCRUNSTINTERCEPT__libc_start_main PARAMS_START_MAIN
175 {
176  hpcrun_libc_start_main(main, argc, ubp_av, init, fini, rtld_fini, stack_end);
177  return 0; /* never reached */
178 }
179 
180 
181 extern int
182 HPCRUNSTINTERCEPT__BP___libc_start_main PARAMS_START_MAIN
183 {
184  hpcrun_libc_start_main(main, argc, ubp_av, init, fini, rtld_fini, stack_end);
185  return 0; /* never reached */
186 }
187 
188 
189 static int
190 hpcrun_libc_start_main PARAMS_START_MAIN
191 {
192  MSG(stderr, "*** static: libc_start_main ***");
193  setenv("HPCRUN_DEBUG", "1", 1);
194 
195  /* squirrel away for later use */
196  hpcrun_cmd = ubp_av[0]; /* command is also in /proc/pid/cmdline */
197  real_start_main_fini = fini;
198 
199  MSG(stderr, "*** static: A ***");
200 
201  /* initialize profiling for process */
202  init_library();
203  init_process();
204 
205  MSG(stderr, "*** static: C ***");
206 
207  /* launch the process */
208  if (opt_debug >= 1) {
209  MSG(stderr, "*** launching intercepted app: %s ***", hpcrun_cmd);
210  }
211 
212  __libc_start_main(main, argc, ubp_av, init, hpcrun_libc_start_main_fini,
213  rtld_fini, stack_end);
214  return 0; /* never reached */
215 }
216 
217 
218 static void
219 hpcrun_libc_start_main_fini()
220 {
221  if (real_start_main_fini) {
222  (*real_start_main_fini)();
223  }
224  fini_process();
225  fini_library();
226  exit(0);
227 }
228 
229 #endif
230 
231 /****************************************************************************
232  * Initialize profiling
233  ****************************************************************************/
234 
235 extern void
237 {
238  if (opt_thread) {
239  MSG(stderr, "FIXME: init_papi_for_process_SPECIALIZED.");
240  }
241 }
242 
243 /****************************************************************************/
244 
245 extern long
247 {
248  return 0; // FIXME
249 }
250 
251 /****************************************************************************/
static Launcher mylauncher
void init_library()
Definition: monitor.c:164
const char * hpcrun_get_cmd(int dbglvl)
Definition: rtmap.c:160
void init_library_SPECIALIZED()
const char * hpcrun_cmd
Definition: monitor.c:136
void fini_process()
Definition: monitor.c:1466
exit
Definition: names.cpp:1
void init_papi_for_process_SPECIALIZED()
int main(int argc, char *argv[])
Definition: main.cpp:125
void fini_library()
Definition: monitor.c:183
int libc_start_main_fptr_t PARAMS_START_MAIN
Definition: monitor.h:214
long hpcrun_gettid_SPECIALIZED()
void init_process()
Definition: monitor.c:430
hpc_threadprof_t opt_thread
Definition: monitor.c:128
int opt_debug
Definition: monitor.c:126