Skip to content

Commit

Permalink
Generate a dump when each of the specified GC memory thresholds are e…
Browse files Browse the repository at this point in the history
…xceeded (#194)

* Refactor procdump/profiler

* initial checkin

* Feature complete

* Update README with new switch and example

* Fix memory leak

* Fixes

* PR feedback

* PR feedback
  • Loading branch information
MarioHewardt authored Jul 10, 2023
1 parent e2cd965 commit cf2341d
Show file tree
Hide file tree
Showing 17 changed files with 715 additions and 180 deletions.
9 changes: 9 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,14 @@
"build": {
// If you want to use a different docker file (such as Dockerfile_Rocky) you can specify it here
"dockerfile": "Dockerfile_Ubuntu"
},
"customizations": {
"vscode": {
"extensions": [
"ms-vscode.cpptools",
"ms-vscode.cpptools-extension-pack",
"ms-vscode.makefile-tools"
]
}
}
}
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ install:
cp procdump.1 $(DESTDIR)$(MANDIR)

$(OBJDIR)/ProcDumpProfiler.so: $(PROFSRCDIR)/ClassFactory.cpp $(PROFSRCDIR)/ProcDumpProfiler.cpp $(PROFSRCDIR)/dllmain.cpp $(PROFSRCDIR)/corprof_i.cpp $(PROFSRCDIR)/easylogging++.cc | $(OBJDIR)
$(PROFCLANG) -o $@ $(PROFCXXFLAGS) -I $(PROFINCDIR) $^
$(PROFCLANG) -o $@ $(PROFCXXFLAGS) -I $(PROFINCDIR) -I $(INCDIR) $^
ld -r -b binary -o $(OBJDIR)/ProcDumpProfiler.o $(OBJDIR)/ProcDumpProfiler.so

$(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR)
Expand Down
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ procdump [-n Count]
[-s Seconds]
[-c|-cl CPU_Usage]
[-m|-ml Commit_Usage1[,Commit_Usage2,...]]
[-gcm Memory_Usage1[,Memory_Usage2...]]
[-tc Thread_Threshold]
[-fc FileDescriptor_Threshold]
[-sig Signal_Number]
Expand All @@ -42,8 +43,9 @@ Options:
-s Consecutive seconds before dump is written (default is 10).
-c CPU threshold above which to create a dump of the process.
-cl CPU threshold below which to create a dump of the process.
-m Memory commit thresholds (MB) above which to create dumps.
-ml Memory commit thresholds (MB) below which to create dumps.
-m Memory commit threshold(s) (MB) above which to create dumps.
-ml Memory commit threshold(s) (MB) below which to create dumps.
-gcm [.NET] GC memory threshold(s) (MB) above which to create dumps.
-tc Thread count threshold above which to create a dump of the process.
-fc File descriptor count threshold above which to create a dump of the process.
-sig Signal number to intercept to create a dump of the process.
Expand Down Expand Up @@ -90,6 +92,10 @@ The following will create a core dump when memory usage is >= 100 MB followed by
```
sudo procdump -m 100,200 1234
```
The following will create a core dump when .NET memory usage is >= 100 MB followed by another dump when memory usage is >= 200MB.
```
sudo procdump -gcm 100,200 1234
```
The following will create a core dump in the `/tmp` directory immediately.
```
sudo procdump 1234 /tmp
Expand Down
1 change: 1 addition & 0 deletions include/Includes.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "ProfilerCommon.h"
#include "CoreDumpWriter.h"
#include "Events.h"
#include "GenHelpers.h"
Expand Down
5 changes: 4 additions & 1 deletion include/Monitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ bool IsQuit(struct ProcDumpConfiguration *self);
int SetQuit(struct ProcDumpConfiguration *self, int quit);
bool ContinueMonitoring(struct ProcDumpConfiguration *self);
bool BeginMonitoring(struct ProcDumpConfiguration *self);
bool MonitorDotNet(struct ProcDumpConfiguration *self);
char* GetThresholds(struct ProcDumpConfiguration *self);
char* GetClientData(struct ProcDumpConfiguration *self, char* fullDumpPath);

// Monitor worker threads
void *CommitMonitoringThread(void *thread_args /* struct ProcDumpConfiguration* */);
Expand All @@ -38,7 +41,7 @@ void *ThreadCountMonitoringThread(void *thread_args /* struct ProcDumpConfigurat
void *FileDescriptorCountMonitoringThread(void *thread_args /* struct ProcDumpConfiguration* */);
void *SignalMonitoringThread(void *thread_args /* struct ProcDumpConfiguration* */);
void *TimerThread(void *thread_args /* struct ProcDumpConfiguration* */);
void *ExceptionMonitoringThread(void *thread_args /* struct ProcDumpConfiguration* */);
void *DotNetMonitoringThread(void *thread_args /* struct ProcDumpConfiguration* */);
void *ProcessMonitor(void *thread_args /* struct ProcDumpConfiguration* */);
void *WaitForProfilerCompletion(void *thread_args /* struct ProcDumpConfiguration* */);

Expand Down
13 changes: 2 additions & 11 deletions include/ProcDumpConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,6 @@
// Structs
// -------------------

enum TriggerType
{
Processor,
Commit,
Timer,
Signal,
ThreadCount,
FileDescriptorCount,
Exception
};

struct TriggerThread
{
pthread_t thread;
Expand Down Expand Up @@ -96,8 +85,10 @@ struct ProcDumpConfiguration {
int CpuThreshold; // -c
bool bCpuTriggerBelowValue; // -cl
int* MemoryThreshold; // -m
int MemoryThresholdCount;
int MemoryCurrentThreshold;
bool bMemoryTriggerBelowValue; // -m or -ml
bool bMonitoringGCMemory; // -gcm
int ThresholdSeconds; // -s
bool bTimerThreshold; // -s
int NumberOfDumpsToCollect; // -n
Expand Down
24 changes: 24 additions & 0 deletions include/ProfilerCommon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License

//--------------------------------------------------------------------
//
// Profiler Common
//
//--------------------------------------------------------------------
#ifndef PROFILERCOMMON_H
#define PROFILERCOMMON_H

enum TriggerType
{
Processor,
Commit,
Timer,
Signal,
ThreadCount,
FileDescriptorCount,
Exception,
GCThreshold
};

#endif // PROFILERCOMMON_H
4 changes: 2 additions & 2 deletions include/ProfilerHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
#define PROFILER_FILE_NAME "procdumpprofiler.so"
#define PROFILER_GUID "{cf0d821e-299b-5307-a3d8-b283c03916dd}"

int InjectProfiler(pid_t pid, char* filter, char* fullDumpPath);
int LoadProfiler(pid_t pid, char* filter, char* fullDumpPath);
int InjectProfiler(pid_t pid, char* clientData);
int LoadProfiler(pid_t pid, char* clientData);
int ExtractProfiler();
char* GetEncodedExceptionFilter(char* exceptionFilterCmdLine, unsigned int numDumps);

Expand Down
11 changes: 9 additions & 2 deletions profiler/inc/ProcDumpProfiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "cor.h"
#include "corprof.h"
#include "profilerstring.h"
#include "ProfilerCommon.h"
#include "easylogging++.h"

#define DETACH_TIMEOUT 30000
Expand Down Expand Up @@ -103,16 +104,20 @@ class CorProfiler : public ICorProfilerCallback8
ICorProfilerInfo* corProfilerInfo;
ICorProfilerInfo8* corProfilerInfo8;
std::vector<struct ExceptionMonitorEntry> exceptionMonitorList;
std::vector<uint64_t> gcMemoryThresholdMonitorList;
pthread_t healthThread;
std::string processName;
std::string fullDumpPath;
pthread_mutex_t endDumpCondition;
enum TriggerType triggerType;
int currentThresholdIndex;
bool gen2Collection;

String GetExceptionName(ObjectID objectId);
String GetExceptionMessage(ObjectID objectId);
bool ParseClientData(char* fw);
bool ParseClientData(char* clientData);
WCHAR* GetUint16(char* buffer);
std::string GetDumpName(uint16_t dumpCount,std::string exceptionName);
std::string GetDumpName(uint16_t dumpCount, std::string name);
std::string GetProcessName();
bool GenerateCoreClrDump(char* socketName, char* dumpFileName);
bool IsCoreClrProcess(pid_t pid, char** socketName);
Expand All @@ -122,6 +127,8 @@ class CorProfiler : public ICorProfilerCallback8
int send_all(int socket, void* buffer, size_t length);
int recv_all(int socket, void* buffer, size_t length);
bool WildcardSearch(WCHAR*, WCHAR*);
u_int64_t GetGCHeapSize();
bool WriteDumpHelper(std::string dumpName);

public:
CorProfiler();
Expand Down
Loading

0 comments on commit cf2341d

Please sign in to comment.