proccontrol: Fix Coverity UNINIT_CTOR errors
[dyninst.git] / proccontrol / src / processplat.C
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 #include "proccontrol/h/PlatFeatures.h"
32 #include "proccontrol/h/Mailbox.h"
33 #include "proccontrol/src/int_process.h"
34 #include "proccontrol/src/procpool.h"
35 #include "proccontrol/src/processplat.h"
36 #include "proccontrol/src/int_event.h"
37
38 using namespace Dyninst;
39 using namespace ProcControlAPI;
40 using namespace std;
41
42 bool int_libraryTracking::default_track_libs = true;
43
44 LibraryTracking::LibraryTracking(Process::ptr proc_) :
45    proc(proc_)
46 {
47 }
48
49 LibraryTracking::~LibraryTracking()
50 {
51    proc = Process::weak_ptr();
52 }
53
54 void LibraryTracking::setDefaultTrackLibraries(bool b)
55 {
56    MTLock lock_this_func(MTLock::allow_init);
57    int_libraryTracking::default_track_libs = b;
58 }
59
60 bool LibraryTracking::getDefaultTrackLibraries()
61 {
62    MTLock lock_this_func(MTLock::allow_init);
63    return int_libraryTracking::default_track_libs;
64 }
65
66 bool LibraryTracking::setTrackLibraries(bool b) const
67 {
68    MTLock lock_this_func;
69    Process::ptr p = proc.lock();
70    PTR_EXIT_TEST(p, "setTrackLibraries", false);
71    ProcessSet::ptr pset = ProcessSet::newProcessSet(p);
72    return pset->getLibraryTracking()->setTrackLibraries(b);
73 }
74
75 bool LibraryTracking::getTrackLibraries() const
76 {
77    MTLock lock_this_func;
78    Process::ptr p = proc.lock();
79    PTR_EXIT_TEST(p, "getTrackLibraries", false);
80    int_libraryTracking *llproc = p->llproc()->getLibraryTracking();
81    assert(llproc);
82    return llproc->isTrackingLibraries();
83 }
84
85 bool LibraryTracking::refreshLibraries()
86 {
87    MTLock lock_this_func;
88    Process::ptr p = proc.lock();
89    PTR_EXIT_TEST(p, "refreshLibraries", false);
90    ProcessSet::ptr pset = ProcessSet::newProcessSet(p);
91    return pset->getLibraryTracking()->refreshLibraries();
92 }
93
94 bool ThreadTracking::default_track_threads = true;
95
96 ThreadTracking::ThreadTracking(Process::ptr proc_) :
97    proc(proc_)
98 {
99 }
100
101 ThreadTracking::~ThreadTracking()
102 {
103    proc = Process::weak_ptr();
104 }
105
106 void ThreadTracking::setDefaultTrackThreads(bool b) 
107 {
108    MTLock lock_this_func(MTLock::allow_init);
109    default_track_threads = b;
110 }
111
112 bool ThreadTracking::getDefaultTrackThreads()
113 {
114    MTLock lock_this_func(MTLock::allow_init);
115    return default_track_threads;
116 }
117
118 bool ThreadTracking::setTrackThreads(bool b) const
119 {
120    MTLock lock_this_func;
121    Process::ptr p = proc.lock();
122    assert(p);
123    ProcessSet::ptr pset = ProcessSet::newProcessSet(p);
124    return pset->getThreadTracking()->setTrackThreads(b);
125 }
126
127 bool ThreadTracking::getTrackThreads() const
128 {
129    MTLock lock_this_func;
130    Process::ptr p = proc.lock();
131    assert(p);
132    int_threadTracking *llproc = p->llproc()->getThreadTracking();
133    assert(llproc);
134    return llproc->isTrackingThreads();
135 }
136
137 bool ThreadTracking::refreshThreads()
138 {
139    MTLock lock_this_func;
140    Process::ptr p = proc.lock();
141    assert(p);
142    ProcessSet::ptr pset = ProcessSet::newProcessSet(p);
143    return pset->getThreadTracking()->refreshThreads();
144 }
145
146 bool LWPTracking::default_track_lwps = true;
147 LWPTracking::LWPTracking(Process::ptr proc_) :
148    proc(proc_)
149 {
150 }
151
152 LWPTracking::~LWPTracking()
153 {
154    proc = Process::weak_ptr();
155 }
156
157 void LWPTracking::setDefaultTrackLWPs(bool b)
158 {
159    MTLock lock_this_func(MTLock::allow_init);
160    default_track_lwps = b;
161 }
162
163 bool LWPTracking::getDefaultTrackLWPs()
164 {
165    MTLock lock_this_func(MTLock::allow_init);
166    return default_track_lwps;
167 }
168
169 void LWPTracking::setTrackLWPs(bool b) const
170 {
171    MTLock lock_this_func;
172    Process::ptr p = proc.lock();
173    if (!p || !p->llproc()) {
174       perr_printf("setTrackLWPs attempted on exited process\n");
175       globalSetLastError(err_exited, "Process is exited\n");
176       return;
177    }
178    int_LWPTracking *llproc = p->llproc()->getLWPTracking();;   
179    llproc->lwp_setTracking(b);
180 }
181
182 bool LWPTracking::getTrackLWPs() const
183 {
184    MTLock lock_this_func;
185    Process::ptr p = proc.lock();
186    PTR_EXIT_TEST(p, "getTrackLWPs", false);
187    int_LWPTracking *llproc = p->llproc()->getLWPTracking();;   
188    return llproc->lwp_getTracking();
189 }
190
191 bool LWPTracking::refreshLWPs()
192 {
193    MTLock lock_this_func;
194    Process::ptr p = proc.lock();
195    PTR_EXIT_TEST(p, "refreshLWPs", false);
196    int_LWPTracking *llproc = p->llproc()->getLWPTracking();;   
197    return llproc->lwp_refresh();
198 }
199
200 FollowFork::FollowFork(Process::ptr proc_) :
201    proc(proc_)
202 {
203 }
204
205 FollowFork::~FollowFork()
206 {
207    proc = Process::weak_ptr();
208 }
209
210 FollowFork::follow_t FollowFork::default_should_follow_fork = FollowFork::Follow;
211
212 void FollowFork::setDefaultFollowFork(FollowFork::follow_t f) {
213    MTLock lock_this_func(MTLock::allow_init);
214    default_should_follow_fork = f;
215 }
216
217 FollowFork::follow_t FollowFork::getDefaultFollowFork()
218 {
219    MTLock lock_this_func(MTLock::allow_init);
220    return default_should_follow_fork;
221 }
222
223 bool FollowFork::setFollowFork(FollowFork::follow_t f) const
224 {
225    MTLock lock_this_func;
226    Process::ptr p = proc.lock();
227    PTR_EXIT_TEST(p, "setFollowFork", false);
228    int_followFork *llproc = p->llproc()->getFollowFork();
229    return llproc->fork_setTracking(f);
230 }
231
232 FollowFork::follow_t FollowFork::getFollowFork() const
233 {
234    MTLock lock_this_func;
235    Process::ptr p = proc.lock();
236    PTR_EXIT_TEST(p, "setFollowFork", None);
237    int_followFork *llproc = p->llproc()->getFollowFork();
238    return llproc->fork_isTracking();
239 }
240
241 CallStackUnwinding::CallStackUnwinding(Thread::ptr t) :
242    wt(t)
243 {
244 }
245
246 CallStackUnwinding::~CallStackUnwinding()
247 {
248 }
249
250 bool CallStackUnwinding::walkStack(CallStackCallback *stk_cb) const
251 {
252    MTLock lock_this_func;
253    Thread::ptr thr = wt.lock();
254    if (!thr) {
255       perr_printf("CallStackUnwinding called on exited thread\n");
256       globalSetLastError(err_exited, "Thread is exited\n");
257       return false;
258    }
259    ThreadSet::ptr thrset = ThreadSet::newThreadSet(thr);
260    return thrset->getCallStackUnwinding()->walkStack(stk_cb);
261 }
262
263 CallStackCallback::CallStackCallback() :
264    top_first(top_first_default_value)
265 {
266 }
267
268 CallStackCallback::~CallStackCallback()
269 {
270 }
271
272 string MultiToolControl::default_tool_name("pcontrl");
273 MultiToolControl::priority_t MultiToolControl::default_tool_priority = 99;
274
275 MultiToolControl::MultiToolControl(Process::ptr p) :
276    proc(p)
277 {
278 }
279
280 MultiToolControl::~MultiToolControl()
281 {
282    proc = Process::weak_ptr();
283 }
284
285 void MultiToolControl::setDefaultToolName(string name) 
286 {
287    MTLock lock_this_func(MTLock::allow_init);
288    default_tool_name = name;
289 }
290
291 void MultiToolControl::setDefaultToolPriority(MultiToolControl::priority_t p)
292 {
293    MTLock lock_this_func(MTLock::allow_init);
294    default_tool_priority = p;
295 }
296
297 string MultiToolControl::getDefaultToolName()
298 {
299    MTLock lock_this_func(MTLock::allow_init);
300    return default_tool_name;
301 }
302
303 MultiToolControl::priority_t MultiToolControl::getDefaultToolPriority()
304 {
305    MTLock lock_this_func(MTLock::allow_init);
306    return default_tool_priority;
307 }
308
309 std::string MultiToolControl::getToolName() const
310 {
311    MTLock lock_this_func;
312    Process::ptr p = proc.lock();
313    PTR_EXIT_TEST(p, "getToolName", string());
314    int_multiToolControl *llproc = p->llproc()->getMultiToolControl();
315    return llproc->mtool_getName();
316 }
317
318 MultiToolControl::priority_t MultiToolControl::getToolPriority() const
319 {
320    MTLock lock_this_func;
321    Process::ptr p = proc.lock();
322    PTR_EXIT_TEST(p, "getToolPriority", 0);
323    int_multiToolControl *llproc = p->llproc()->getMultiToolControl();
324    return llproc->mtool_getPriority();
325 }
326
327 MemoryUsage::MemoryUsage(Process::ptr proc_) :
328    proc(proc_)
329 {
330 }
331
332 MemoryUsage::~MemoryUsage()
333 {
334    proc = Process::weak_ptr();
335 }
336
337 bool MemoryUsage::sharedUsed(unsigned long &used) const
338 {
339    MTLock lock_this_func;
340    Process::ptr p = proc.lock();
341    PTR_EXIT_TEST(p, "sharedUsed", false);
342    int_memUsage *llproc = p->llproc()->getMemUsage();
343    unsigned long val;
344    
345    MemUsageResp_t mem_response(&val, llproc);
346    bool result = llproc->plat_getSharedUsage(&mem_response);
347    if (!result) {
348       perr_printf("Error getting shared usage\n");
349       return false;
350    }
351    
352    llproc->waitForEvent(&mem_response);
353    used = *mem_response.get();
354    return true;
355 }
356
357 bool MemoryUsage::heapUsed(unsigned long &used) const
358 {
359    MTLock lock_this_func;
360    Process::ptr p = proc.lock();
361    PTR_EXIT_TEST(p, "heapUsed", false);
362    int_memUsage *llproc = p->llproc()->getMemUsage();
363    unsigned long val;
364    
365    MemUsageResp_t mem_response(&val, llproc);
366    bool result = llproc->plat_getHeapUsage(&mem_response);
367    if (!result) {
368       perr_printf("Error getting heap usage\n");
369       return false;
370    }
371    
372    llproc->waitForEvent(&mem_response);
373    used = *mem_response.get();
374    return true;
375 }
376
377 bool MemoryUsage::stackUsed(unsigned long &used) const
378 {
379    MTLock lock_this_func;
380    Process::ptr p = proc.lock();
381    PTR_EXIT_TEST(p, "stackUsed", false);
382    int_memUsage *llproc = p->llproc()->getMemUsage();
383    unsigned long val;
384    
385    MemUsageResp_t mem_response(&val, llproc);
386    bool result = llproc->plat_getStackUsage(&mem_response);
387    if (!result) {
388       perr_printf("Error getting stack usage\n");
389       return false;
390    }
391    
392    llproc->waitForEvent(&mem_response);
393    used = *mem_response.get();
394    return true;
395 }
396
397 dyn_sigset_t SignalMask::default_sigset;
398 bool SignalMask::sigset_initialized = false;
399
400 SignalMask::SignalMask(Process::ptr proc_) :
401    proc(proc_)
402 {
403 }
404
405 SignalMask::~SignalMask()
406 {
407 }
408
409 dyn_sigset_t SignalMask::getSigMask() const
410 {
411    MTLock lock_this_func;
412    Process::ptr p = proc.lock();
413    PTR_EXIT_TEST(p, "getSigMask", SignalMask::default_sigset);
414    int_signalMask *llproc = p->llproc()->getSignalMask();
415    return llproc->getSigMask();
416 }
417
418 bool SignalMask::setSigMask(dyn_sigset_t s)
419 {
420    MTLock lock_this_func;
421    Process::ptr p = proc.lock();
422    PTR_EXIT_TEST(p, "getSigMask", false);
423    int_signalMask *llproc = p->llproc()->getSignalMask();
424    llproc->setSigMask(s);
425    return true;
426 }
427
428 dyn_sigset_t SignalMask::getDefaultSigMask()
429 {
430    if (!sigset_initialized) {
431 #if !defined(os_windows)
432       sigfillset(&default_sigset);
433 #endif
434       sigset_initialized = true;
435    }
436    return default_sigset;
437 }
438
439 void SignalMask::setDefaultSigMask(dyn_sigset_t s)
440 {
441    sigset_initialized = true;
442    default_sigset = s;
443 }
444
445 BGQData::BGQData(Process::ptr proc_) :
446    proc(proc_)
447 {
448 }
449
450 BGQData::~BGQData()
451 {
452 }
453
454 void BGQData::setStartupTimeout(unsigned int seconds)
455 {
456    int_BGQData::startup_timeout_sec = seconds;
457 }
458
459 void BGQData::setBlockForControlAuthority(bool block)
460 {
461    int_BGQData::block_for_ca = block;
462 }
463    
464 bool BGQData::getProcCoordinates(unsigned &a, unsigned &b, unsigned &c, unsigned &d, unsigned &e, unsigned &t) const
465 {
466    MTLock lock_this_func;
467    Process::ptr p = proc.lock();
468    PTR_EXIT_TEST(p, "getProcCoordinates", false);
469    int_BGQData *proc = p->llproc()->getBGQData();
470    proc->bgq_getProcCoordinates(a, b, c, d, e, t);
471    return true;
472 }
473
474 unsigned int BGQData::getComputeNodeID() const
475 {
476    MTLock lock_this_func;
477    Process::ptr p = proc.lock();
478    PTR_EXIT_TEST(p, "getComputeNodeID", 0);
479    int_BGQData *proc = p->llproc()->getBGQData();
480    return proc->bgq_getComputeNodeID();
481 }
482
483 bool BGQData::getSharedMemRange(Dyninst::Address &start, Dyninst::Address &end) const
484 {
485    MTLock lock_this_func;
486    Process::ptr p = proc.lock();
487    PTR_EXIT_TEST(p, "getSharedMemRange", false);
488    int_BGQData *proc = p->llproc()->getBGQData();
489    proc->bgq_getSharedMemRange(start, end);
490    return true;
491 }
492
493 bool BGQData::getPersistantMemRange(Dyninst::Address &start, Dyninst::Address &end) const
494 {
495    MTLock lock_this_func;
496    Process::ptr p = proc.lock();
497    PTR_EXIT_TEST(p, "getPersistantMemRange", false);
498    int_BGQData *proc = p->llproc()->getBGQData();
499    proc->bgq_getPersistantMemRange(start, end);
500    return true;
501 }
502
503 bool BGQData::getHeapMemRange(Dyninst::Address &start, Dyninst::Address &end) const
504 {
505    MTLock lock_this_func;
506    Process::ptr p = proc.lock();
507    PTR_EXIT_TEST(p, "getHeapMemRange", false);
508    int_BGQData *proc = p->llproc()->getBGQData();
509    proc->bgq_getHeapMemRange(start, end);
510    return true;
511 }
512
513 FileInfo::FileInfo(std::string f)
514 {
515    info = int_fileInfo_ptr(new int_fileInfo());
516    info->filename = f;
517 }
518
519 FileInfo::FileInfo()
520 {   
521 }
522
523 FileInfo::FileInfo(const FileInfo &fi)
524 {
525    info = fi.info;
526 }
527
528 FileInfo::~FileInfo() 
529 {
530 }
531
532 std::string FileInfo::getFilename() const
533 {
534    if (!info)
535       return std::string();
536    return info->filename;
537 }
538
539 stat64_ptr FileInfo::getStatResults() const
540 {
541    if (!info)
542       return NULL;
543    return info->stat_results;
544 }
545
546 int_fileInfo_ptr FileInfo::getInfo() const
547 {
548    if (!info)
549       info = int_fileInfo_ptr(new int_fileInfo());
550    return info;
551 }
552
553 RemoteIO::RemoteIO(Process::ptr proc_) :
554    proc(proc_)
555 {
556 }
557
558 RemoteIO::~RemoteIO()
559 {
560 }
561
562 FileSet *RemoteIO::getFileSet(string filename) const
563 {
564    MTLock lock_this_func;
565    Process::ptr p = proc.lock();
566    PTR_EXIT_TEST(p, "getFileSet", NULL);
567    FileSet *new_fs = new FileSet();
568    new_fs->insert(make_pair(static_cast<Process::const_ptr>(p), FileInfo(filename)));
569    return new_fs;
570 }
571
572 FileSet *RemoteIO::getFileSet(const set<string> &filenames) const
573 {
574    MTLock lock_this_func;
575    Process::ptr p = proc.lock();
576    PTR_EXIT_TEST(p, "getFielSet", NULL);
577    FileSet *new_fs = new FileSet();
578    
579    for (set<string>::const_iterator i = filenames.begin(); i != filenames.end(); i++) {
580       new_fs->insert(make_pair(static_cast<Process::const_ptr>(p), FileInfo(*i)));
581    }
582    return new_fs;
583 }
584
585 bool RemoteIO::addToFileSet(std::string filename, FileSet *fs) const
586 {
587    MTLock lock_this_func;
588    Process::const_ptr p = proc.lock();
589    PTR_EXIT_TEST(p, "addToFileSet", false);
590    fs->insert(make_pair(p, FileInfo(filename)));
591    return true;
592 }
593
594 bool RemoteIO::getFileNames(FileSet *fset) const
595 {
596    MTLock lock_this_func;
597    Process::ptr p = proc.lock();
598    PTR_EXIT_TEST(p, "getFileNames", false);
599    int_remoteIO *proc = p->llproc()->getRemoteIO();
600    return proc->getFileNames(fset);
601 }
602
603 bool RemoteIO::getFileStatData(FileSet *fset) const
604 {
605    MTLock lock_this_func;
606    Process::ptr p = proc.lock();
607    PTR_EXIT_TEST(p, "getStatData", false);
608    int_remoteIO *proc = p->llproc()->getRemoteIO();
609    return proc->getFileStatData(*fset);
610 }
611
612 bool RemoteIO::readFileContents(const FileSet *fset)
613 {
614    MTLock lock_this_func;
615    Process::ptr p = proc.lock();
616    PTR_EXIT_TEST(p, "getStatData", false);
617    int_remoteIO *proc = p->llproc()->getRemoteIO();
618    return proc->getFileDataAsync(*fset);
619 }
620
621 RemoteIOSet::RemoteIOSet(ProcessSet::ptr procs_) 
622 {
623    pset = procs_;
624 }
625
626 RemoteIOSet::~RemoteIOSet()
627 {
628 }
629
630 FileSet *RemoteIOSet::getFileSet(string filename)
631 {
632    ProcessSet::ptr procs = pset.lock();
633    if (!procs || procs->empty()) {
634       globalSetLastError(err_badparam, "Cannot create fileset from empty process set");
635       return NULL;
636    }
637
638    FileSet *new_fs = new FileSet();
639    for (ProcessSet::iterator i = procs->begin(); i != procs->end(); i++) {
640       new_fs->insert(make_pair(*i, FileInfo(filename)));
641    }
642    return new_fs;
643 }
644
645 FileSet *RemoteIOSet::getFileSet(const set<string> &filenames)
646 {
647    ProcessSet::ptr procs = pset.lock();
648    if (!procs || procs->empty()) {
649       globalSetLastError(err_badparam, "Cannot create fileset from empty process set");
650       return NULL;
651    }
652    if (filenames.empty()) {
653       globalSetLastError(err_badparam, "Cannot create a fileset from empty list of names");
654       return NULL;
655    }
656
657    FileSet *new_fs = new FileSet();
658    for (ProcessSet::iterator i = procs->begin(); i != procs->end(); i++) {
659       for (set<string>::iterator j = filenames.begin(); j != filenames.end(); j++) {
660          new_fs->insert(make_pair(*i, *j));
661       }
662    }
663    return new_fs;
664 }
665
666 bool RemoteIOSet::addToFileSet(string filename, FileSet *fs)
667 {
668    ProcessSet::ptr procs = pset.lock();
669    if (!procs || procs->empty()) {
670       globalSetLastError(err_badparam, "Cannot add empty process et to fileset");
671       return false;
672    }
673    if (!fs) {
674       globalSetLastError(err_badparam, "NULL FileSet parameter\n");
675       return false;
676    }
677    for (ProcessSet::iterator i = procs->begin(); i != procs->end(); i++) {
678       fs->insert(make_pair(*i, filename));
679    }
680    return true;
681 }
682
683 int_libraryTracking::int_libraryTracking(Dyninst::PID p, string e, vector<string> a, 
684                                          vector<string> envp, map<int,int> f) :
685    int_process(p, e, a, envp, f),
686    up_ptr(NULL)
687 {
688 }
689
690 int_libraryTracking::int_libraryTracking(Dyninst::PID pid_, int_process *p) :
691    int_process(pid_, p),
692    up_ptr(NULL)
693 {
694 }
695
696 int_libraryTracking::~int_libraryTracking()
697 {
698    if (up_ptr) {
699       delete up_ptr;
700       up_ptr = NULL;
701    }
702 }
703
704 int_LWPTracking::int_LWPTracking(Dyninst::PID p, string e, vector<string> a,
705                                  vector<string> envp, map<int,int> f) :
706    int_process(p, e, a, envp, f),
707    lwp_tracking(LWPTracking::default_track_lwps),
708    up_ptr(NULL)
709 {
710 }
711
712 int_LWPTracking::int_LWPTracking(Dyninst::PID pid_, int_process *p) :
713    int_process(pid_, p),
714    lwp_tracking(p->getLWPTracking()->lwp_tracking),
715    up_ptr(NULL)
716 {
717 }
718
719 int_LWPTracking::~int_LWPTracking()
720 {
721    if (up_ptr) {
722       delete up_ptr;
723       up_ptr = NULL;
724    }
725 }
726
727 bool int_LWPTracking::lwp_setTracking(bool b)
728 {
729    pthrd_printf("Changing lwp tracking in %d from %s to %s\n", getPid(),
730                 lwp_tracking ? "true" : "false", b ? "true" : "false");
731    if (b == lwp_tracking)
732       return true;
733    lwp_tracking = b;
734    return plat_lwpChangeTracking(b);
735 }
736
737 bool int_LWPTracking::plat_lwpChangeTracking(bool)
738 {
739    return true;
740 }
741
742 bool int_LWPTracking::lwp_getTracking()
743 {
744    return lwp_tracking;
745 }
746
747 bool int_LWPTracking::lwp_refresh()
748 {
749    pthrd_printf("Refreshing LWPs in process %d\n", getPid());
750    result_response::ptr resp;
751    bool result = lwp_refreshPost(resp);
752    if (!result) {
753       pthrd_printf("Error from lwp_refreshPost\n");
754       return false;
755    }
756    if (resp) {
757       int_process::waitForAsyncEvent(resp);
758    }
759    bool change;
760    result = lwp_refreshCheck(change);
761    if (!result) {
762       pthrd_printf("Failed to check for new LWPs");
763       return false;
764    }
765    
766    if (!change)
767       return true;
768    
769    setForceGeneratorBlock(true);
770    ProcPool()->condvar()->lock();
771    ProcPool()->condvar()->broadcast();
772    ProcPool()->condvar()->unlock();
773    int_process::waitAndHandleEvents(false);
774    setForceGeneratorBlock(false);
775    return true;
776 }
777
778 bool int_LWPTracking::plat_lwpRefresh(result_response::ptr)
779 {
780    return false;
781 }
782
783 bool int_LWPTracking::lwp_refreshPost(result_response::ptr &resp)
784 {
785    if (!plat_needsAsyncIO()) {
786       resp = result_response::ptr();
787       return true;
788    }
789    
790    resp = result_response::createResultResponse();
791    resp->setProcess(this);
792    resp->markSyncHandled();
793    
794    getResponses().lock();
795    bool result = plat_lwpRefresh(resp);
796    if (result) {
797       getResponses().addResponse(resp, this);
798    }
799    if (!result) {
800       resp = result_response::ptr();
801    }
802    getResponses().unlock();
803    getResponses().noteResponse();
804    
805    return true;
806 }
807
808 bool int_LWPTracking::lwp_refreshCheck(bool &change)
809 {
810    vector<Dyninst::LWP> lwps;
811    change = false;
812    bool result = getThreadLWPs(lwps);
813    if (!result) {
814       pthrd_printf("Error calling getThreadLWPs during refresh\n");
815       return false;
816    }
817    
818    //Look for added LWPs
819    int_threadPool *pool = threadPool();
820    int new_lwps_found = 0;
821    for (vector<Dyninst::LWP>::iterator i = lwps.begin(); i != lwps.end(); i++) {
822       Dyninst::LWP lwp = *i;
823       int_thread *thr = pool->findThreadByLWP(*i);
824       if (thr)
825          continue;
826       pthrd_printf("Found new thread %d/%d during refresh\n", getPid(), lwp);
827       thr = int_thread::createThread(this, NULL_THR_ID, *i, false, int_thread::as_needs_attach);
828       new_lwps_found++;
829       change = true;
830       plat_lwpRefreshNoteNewThread(thr);
831    }
832    
833    //Look for removed LWPs
834    if (lwps.size() - new_lwps_found != pool->size()) {     
835       for (int_threadPool::iterator i = pool->begin(); i != pool->end(); i++) {
836          int_thread *thr = *i;
837          bool found = false;
838          for (vector<Dyninst::LWP>::iterator j = lwps.begin(); j != lwps.end(); j++) {
839             if (thr->getLWP() == *j) {
840                found = true;
841                break;
842             }
843          }
844          if (found)
845             continue;
846          change = true;
847          pthrd_printf("Found thread %d/%d is dead during refresh\n", getPid(), thr->getLWP());
848          EventLWPDestroy::ptr newev = EventLWPDestroy::ptr(new EventLWPDestroy(EventType::Pre));
849          newev->setProcess(proc());
850          newev->setThread(thr->thread());
851          newev->setSyncType(Event::async);
852          mbox()->enqueue(newev);
853       }
854    }
855
856    return true;
857 }
858
859 bool int_LWPTracking::plat_lwpRefreshNoteNewThread(int_thread *)
860 {
861    return true;
862 }
863
864 int_threadTracking::int_threadTracking(Dyninst::PID p, string e, vector<string> a,
865                                        vector<string> envp, map<int,int> f) :
866    int_process(p, e, a, envp, f),
867    up_ptr(NULL)
868 {
869 }
870
871 int_threadTracking::int_threadTracking(Dyninst::PID pid_, int_process *p) :
872    int_process(pid_, p),
873    up_ptr(NULL)
874 {
875 }
876
877 int_threadTracking::~int_threadTracking()
878 {
879    if (up_ptr) {
880       delete up_ptr;
881       up_ptr = NULL;
882    }
883 }
884
885 int_followFork::int_followFork(Dyninst::PID p, string e, vector<string> a,
886                                vector<string> envp, map<int,int> f) :
887    int_process(p, e, a, envp, f),
888    fork_tracking(FollowFork::default_should_follow_fork),
889    up_ptr(NULL)
890 {
891 }
892
893 int_followFork::int_followFork(Dyninst::PID pid_, int_process *p) :
894    int_process(pid_, p),
895    fork_tracking(p->getFollowFork()->fork_tracking),
896    up_ptr(NULL)
897 {
898 }
899
900 int_followFork::~int_followFork()
901 {
902    if (up_ptr) {
903       delete up_ptr;
904       up_ptr = NULL;
905    }
906 }
907
908 int_multiToolControl::int_multiToolControl(Dyninst::PID p, string e, vector<string> a,
909                                            vector<string> envp, map<int,int> f) :
910    int_process(p, e, a, envp, f),
911    up_ptr(NULL)
912 {
913 }
914
915 int_multiToolControl::int_multiToolControl(Dyninst::PID pid_, int_process *p) :
916    int_process(pid_, p),
917    up_ptr(NULL)
918 {
919 }
920
921 int_multiToolControl::~int_multiToolControl()
922 {
923    if (up_ptr) {
924       delete up_ptr;
925       up_ptr = NULL;
926    }
927 }
928
929 int_signalMask::int_signalMask(Dyninst::PID p, string e, vector<string> a,
930                                vector<string> envp, map<int,int> f) :
931    int_process(p, e, a, envp, f),
932    sigset(SignalMask::getDefaultSigMask()),
933    up_ptr(NULL)
934 {   
935 }
936
937 int_signalMask::int_signalMask(Dyninst::PID pid_, int_process *p) :
938    int_process(pid_, p),
939    sigset(SignalMask::getDefaultSigMask()),
940    up_ptr(NULL)
941 {
942 }
943
944 int_signalMask::~int_signalMask()
945 {
946    if (up_ptr) {
947       delete up_ptr;
948       up_ptr = NULL;
949    }
950 }
951
952 int_callStackUnwinding::int_callStackUnwinding(Dyninst::PID p, string e, vector<string> a,
953                                                vector<string> envp, map<int,int> f) :
954    int_process(p, e, a, envp, f)
955 {
956 }
957
958 int_callStackUnwinding::int_callStackUnwinding(Dyninst::PID pid_, int_process *p) :
959    int_process(pid_, p)
960 {
961 }
962
963 int_callStackUnwinding::~int_callStackUnwinding()
964 {
965 }
966
967 int_memUsage::int_memUsage(Dyninst::PID p, std::string e, std::vector<std::string> a,
968                            std::vector<std::string> envp, std::map<int,int> f) :
969    int_process(p, e, a, envp, f),
970    resp_process(p, e, a, envp, f),
971    up_ptr(NULL)
972 {
973 }
974
975 int_memUsage::int_memUsage(Dyninst::PID pid_, int_process *p) :
976    int_process(pid_, p),
977    resp_process(pid_, p),
978    up_ptr(NULL)
979 {
980 }
981
982 int_memUsage::~int_memUsage()
983 {
984    if (up_ptr) {
985       delete up_ptr;
986       up_ptr = NULL;
987    }
988 }
989
990 int_BGQData::int_BGQData(Dyninst::PID p, string e, vector<string> a,
991                          vector<string> envp, map<int,int> f) :
992    int_process(p, e, a, envp, f),
993    up_ptr(NULL)
994 {
995 }
996
997 int_BGQData::int_BGQData(Dyninst::PID pid_, int_process *p) :
998    int_process(pid_, p),
999    up_ptr(NULL)
1000 {
1001 }
1002
1003 int_BGQData::~int_BGQData()
1004 {
1005    if (up_ptr) {
1006       delete up_ptr;
1007       up_ptr = NULL;
1008    }
1009 }
1010
1011 unsigned int int_BGQData::startup_timeout_sec = BGQData::startup_timeout_sec_default;
1012 bool int_BGQData::block_for_ca = BGQData::block_for_ca_default;
1013
1014 int_fileInfo::int_fileInfo() :
1015    stat_results(NULL),
1016    cur_pos(0)
1017 {
1018 }
1019
1020 int_fileInfo::~int_fileInfo()
1021 {
1022    if (stat_results) {
1023       delete stat_results;
1024       stat_results = NULL;
1025    }
1026 }
1027
1028 int_remoteIO::int_remoteIO(Dyninst::PID p, std::string e, std::vector<std::string> a,
1029                            std::vector<std::string> envp, std::map<int,int> f) :
1030    int_process(p, e, a, envp, f),
1031    resp_process(p, e, a, envp, f),
1032    up_ptr(NULL)
1033 {
1034 }
1035
1036 int_remoteIO::int_remoteIO(Dyninst::PID pid_, int_process *p) :
1037    int_process(pid_, p),
1038    resp_process(pid_, p),
1039    up_ptr(NULL)
1040 {
1041 }
1042
1043 int_remoteIO::~int_remoteIO()
1044 {
1045 }
1046
1047 bool int_remoteIO::getFileNames(FileSet *fset)
1048 {
1049    if (!fset) {
1050       perr_printf("Null FileSet passed to getFileNames\n");
1051       setLastError(err_badparam, "Unexpected NULL parameter");
1052       return false;
1053    }
1054    
1055    FileSetResp_t resp(fset, this);
1056    
1057    bool result = plat_getFileNames(&resp);
1058    if (!result) {
1059       perr_printf("Error requesting filenames");
1060       return false;
1061    }
1062
1063    waitForEvent(&resp);
1064    return true;
1065 }
1066
1067 bool int_remoteIO::getFileStatData(FileSet &files)
1068 {
1069    set<StatResp_t *> resps;
1070    bool had_error = false;
1071
1072    for (FileSet::iterator i = files.begin(); i != files.end(); i++) {
1073       if (static_cast<int_process *>(this) != i->first->llproc()) {
1074          perr_printf("Non-local process in fileset, %d specified for %d\n",
1075                      i->first->llproc()->getPid(), getPid());
1076          setLastError(err_badparam, "Non-local process specified in FileSet");
1077          had_error = true;
1078          continue;
1079       }
1080
1081       FileInfo &fi = i->second;
1082       int_fileInfo_ptr info = fi.getInfo();
1083       if (info->filename.empty()) {
1084          perr_printf("Empty filename in stat operation on %d\n", getPid());
1085          setLastError(err_badparam, "Empty filename specified in stat operation");
1086          had_error = true;
1087          continue;
1088       }
1089       
1090       bool result = plat_getFileStatData(info->filename, &info->stat_results, resps);
1091       if (!result) {
1092          pthrd_printf("Error while requesting file data stat on %d\n", getPid());
1093          had_error = true;
1094          continue;
1095       }
1096    }
1097
1098    for (set<StatResp_t *>::iterator i = resps.begin(); i != resps.end(); i++) {
1099       waitForEvent(*i);
1100       delete *i;
1101    }
1102
1103    return !had_error;
1104 }
1105
1106 bool int_remoteIO::getFileDataAsync(const FileSet &files)
1107 {
1108    set<FileReadResp_t *> resps;
1109    bool had_error = false;
1110
1111    for (FileSet::const_iterator i = files.begin(); i != files.end(); i++) {
1112       int_fileInfo_ptr fi = i->second.getInfo();
1113       if (static_cast<int_process *>(this) != i->first->llproc()) {
1114          perr_printf("Non-local process in fileset, %d specified for %d\n",
1115                      i->first->llproc()->getPid(), getPid());
1116          setLastError(err_badparam, "Non-local process specified in FileSet\n");
1117          had_error = true;
1118          continue;
1119       }
1120
1121       int_eventAsyncFileRead *fileread = new int_eventAsyncFileRead();
1122       fileread->offset = 0;
1123       fileread->whole_file = true;
1124       fileread->filename = fi->filename;
1125       fi->cur_pos = 0;
1126       bool result = plat_getFileDataAsync(fileread);
1127       if (!result) {
1128          pthrd_printf("Error while requesting file data on %d\n", getPid());
1129          had_error = true;
1130          delete fileread;
1131          continue;
1132       }
1133    }
1134
1135    return !had_error;
1136 }
1137
1138