Skip to content

Commit

Permalink
finish test call threaddump from go
Browse files Browse the repository at this point in the history
  • Loading branch information
chaolihf committed Feb 15, 2024
1 parent b39ad64 commit 0ff3624
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 65 deletions.
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
"psutil.h": "c",
"syscall.h": "c",
"un.h": "c",
"sockaddr.h": "c"
"sockaddr.h": "c",
"string.h": "c",
"common.h": "c"
},
"cmake.configureOnOpen": false
}
42 changes: 17 additions & 25 deletions pkg/cgo/common.c
Original file line number Diff line number Diff line change
@@ -1,23 +1,6 @@
#include <stdio.h>
#include <stdlib.h>

/**
* 定义一个缓存字符数组长度和指针的节点
*/
struct OutputNode {
int size;
char* buffer;
struct OutputNode* next;
} ;

/**
* 通过一个队列来缓存所有的字符数组,这样在最后可以拼接起来复制成一个字符数组
*/
struct OutputQueue {
struct OutputNode* firstNode;
struct OutputNode* endNode;
int allSize;
};
#include "common.h"

struct OutputQueue* initOutputQueue(){
struct OutputQueue *queue=malloc(sizeof(struct OutputQueue));
Expand Down Expand Up @@ -47,15 +30,24 @@ void addOutputNode(struct OutputQueue *queue,int size,char* buffer){
/**
* 输出所有的数组
*/
void output(struct OutputQueue *queue,unsigned char** byteArray, size_t* length){
*length = queue->allSize;
*byteArray = (unsigned char*)malloc(*length * sizeof(unsigned char));
char result[queue->allSize];
void output(struct OutputQueue *queue,OutputInfo *result){
result->size= queue->allSize;
char *byteArray = (char*)malloc(result->size * sizeof(char));
result->output=byteArray;
struct OutputNode *node=queue->firstNode;
while(node!=NULL){
memcpy(byteArray, node->buffer, node->size);
byteArray+=node->size;
node=node->next;
}
}

void freeQueue(struct OutputQueue *queue){
struct OutputNode *node=queue->firstNode;
int offset=0;
while(node!=NULL){
memcpy(&result[offset], node->buffer, node->size);
offset+=node->size;
struct OutputNode *waitToFreeNode=node;
node=node->next;
free(waitToFreeNode);
}
free(queue);
}
41 changes: 41 additions & 0 deletions pkg/cgo/common.h
Original file line number Diff line number Diff line change
@@ -1 +1,42 @@
#define MAX_PATH 1024
#include <string.h>

#ifndef COMMON_HEAD
#define COMMON_HEAD
/**
* 定义返回结果
*/
typedef struct OutputInfo{
int result;
int size;
char* output;
} OutputInfo;


/**
* 定义一个缓存字符数组长度和指针的节点
*/
struct OutputNode {
int size;
char* buffer;
struct OutputNode* next;
} ;

/**
* 通过一个队列来缓存所有的字符数组,这样在最后可以拼接起来复制成一个字符数组
*/
struct OutputQueue {
struct OutputNode* firstNode;
struct OutputNode* endNode;
int allSize;
};

struct OutputQueue* initOutputQueue();

void addOutputNode(struct OutputQueue *queue,int size,char* buffer);

void output(struct OutputQueue *queue,OutputInfo *result);

void freeQueue(struct OutputQueue *queue);

#endif
36 changes: 21 additions & 15 deletions pkg/cgo/hotspot.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <netinet/in.h>
#include <sys/file.h>
#include <errno.h>
#include "common.h"

// Send command with arguments to socket
static int write_command_hotspot(int fd, char * command, char* arguments) {
Expand Down Expand Up @@ -123,25 +124,31 @@ static int connect_socket(int pid) {

// Mirror response from remote JVM to stdout
static int read_response_hotspot(int fd, char * command, char* arguments, int print_output,
unsigned char** byteArray, size_t* length) {
char buf[8192];
ssize_t bytes = read(fd, buf, sizeof(buf) - 1);
OutputInfo *outputInfo) {
int bufferSize=8192;
char* buf=malloc(bufferSize);
ssize_t bytes = read(fd, buf, bufferSize - 1);
if (bytes == 0) {
fprintf(stderr, "Unexpected EOF reading response\n");
free(buf);
return 1;
} else if (bytes < 0) {
perror("Error reading response");
free(buf);
return 1;
}

// First line of response is the command result code
buf[bytes] = 0;
int result = atoi(buf);

if( result!=0) {
free(buf);
return result;
}
struct OutputQueue *queue=initOutputQueue();
// Special treatment of 'load' command
if (result == 0 && strcmp(command, "load") == 0) {
if (strcmp(command, "load") == 0) {
size_t total = bytes;
while (total < sizeof(buf) - 1 && (bytes = read(fd, buf + total, sizeof(buf) - 1 - total)) > 0) {
while (total < bufferSize - 1 && (bytes = read(fd, buf + total, bufferSize - 1 - total)) > 0) {
total += (size_t)bytes;
}
bytes = total;
Expand All @@ -152,24 +159,23 @@ static int read_response_hotspot(int fd, char * command, char* arguments, int pr
}
else{
// Mirror JVM response to result

do {
fwrite(buf, 1, bytes, stdout);
bytes = read(fd, buf, sizeof(buf));
addOutputNode(queue,bytes,buf);
buf=malloc(bufferSize);
bytes = read(fd, buf, bufferSize);
} while (bytes > 0);
printf("\n");
output(queue,outputInfo);
}
*length = 8192;
*byteArray = (unsigned char*)malloc(*length * sizeof(unsigned char));
memcpy(*byteArray, buf, *length);
freeQueue(queue);
return result;
}




int jattach_hotspot(int pid, int nspid, char * command, char* arguments, int print_output,
int mnt_changed,unsigned char** byteArray, size_t* length) {
int mnt_changed,OutputInfo *outputInfo) {
if (check_socket(nspid) != 0 && start_attach_mechanism(pid, nspid,mnt_changed) != 0) {
perror("Could not start attach mechanism");
return 1;
Expand All @@ -191,7 +197,7 @@ int jattach_hotspot(int pid, int nspid, char * command, char* arguments, int pri
return 1;
}

int result = read_response_hotspot(fd, command, arguments, print_output,byteArray,length);
int result = read_response_hotspot(fd, command, arguments, print_output,outputInfo);
close(fd);

return result;
Expand Down
15 changes: 4 additions & 11 deletions pkg/cgo/jattach.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,8 @@

char tmp_path[MAX_PATH - 100];

int jattach(unsigned char** byteArray, size_t* length,int pid, char * command, char* arguments, int print_output) {
struct OutputQueue *queue=initOutputQueue();
addOutputNode(queue,sizeof("hello"),"hello");
addOutputNode(queue,sizeof("world"),"world");
int size;
char** result;
output(queue,&result,&size);
printf("%s",result);

int jattach(OutputInfo *outputInfo,int pid, char * command, char* arguments, int print_output) {
//OutputInfo *outputInfo=malloc(sizeof(OutputInfo));
printf("jattach %s %s\n",command,arguments);
uid_t my_uid = geteuid();
gid_t my_gid = getegid();
Expand Down Expand Up @@ -63,8 +56,8 @@ int jattach(unsigned char** byteArray, size_t* length,int pid, char * command, c
if (is_openj9_process(nspid)) {
//return jattach_openj9(pid, nspid, argc, argv, print_output);
} else {
jattach_hotspot(pid, nspid, command, arguments, print_output,mnt_changed,byteArray,length);
return 0;
jattach_hotspot(pid, nspid, command, arguments, print_output,mnt_changed,outputInfo);
return 0;
}
return 1;
}
7 changes: 3 additions & 4 deletions pkg/cgo/jattach_test.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#include "jattach.c"

int main(int argc,char ** argv){
size_t length;
char source[81920] ;
jattach(&source,&length,atoi(argv[1]),argv[2],"",1);
return 0;
OutputInfo outputInfo;
int result=jattach(&outputInfo,atoi(argv[1]),argv[2],"",1);
return result;
}
17 changes: 8 additions & 9 deletions pkg/java_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func ScanAllProcess() error {
continue
}
if nsPid > 0 && pid != int(nsPid) {
err := callJavaAttach(pid, "threaddump", "")
content, err := callJavaAttach(pid, "threaddump", "")
if err != nil {
logger.Log(err.Error())
continue
Expand Down Expand Up @@ -123,16 +123,15 @@ func ScanAllProcess() error {
return nil
}

func callJavaAttach(pid int, command string, params string) error {
var byteArray *C.uchar
var length C.size_t
result := C.jattach(&byteArray, &length, C.int(pid), C.CString(command), C.CString(params), C.int(1))
func callJavaAttach(pid int, command string, params string) (string, error) {
var outputInfo C.struct_OutputInfo
result := C.jattach(&outputInfo, C.int(pid), C.CString(command), C.CString(params), C.int(1))
if result == 0 {
goByteArray := C.GoBytes(unsafe.Pointer(byteArray), C.int(length))
logger.Log("INFO", goByteArray)
C.free(unsafe.Pointer(byteArray))
output := C.GoString(outputInfo.output)
C.free(unsafe.Pointer(outputInfo.output))
return output, nil
}
return nil
return "", errors.New("error")
}

/*
Expand Down

0 comments on commit 0ff3624

Please sign in to comment.