Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate a dump when each of the specified GC memory thresholds are exceeded #194

Merged
merged 8 commits into from
Jul 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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