Skip to content

Commit

Permalink
feat: add log to webui
Browse files Browse the repository at this point in the history
Signed-off-by: Zxilly <[email protected]>
  • Loading branch information
Zxilly committed Jul 12, 2024
1 parent 2d3b0fd commit ef38d99
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 16 deletions.
7 changes: 7 additions & 0 deletions internal/knowninfo/dwarf.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@ func (k *KnownInfo) AddDwarfSubProgram(
typ := entity.FuncTypeFunction
receiverName := ""
if isGo {
//defer func(name string) {

Check failure on line 122 in internal/knowninfo/dwarf.go

View workflow job for this annotation

GitHub Actions / GolangCI Lint

comment-spacings: no space between comment delimiter and comment text (revive)
// if r := recover(); r != nil {
// slog.Warn(fmt.Sprintf("Failed to load DWARF function receiver: %s: %v", name, r))
// panic(r)
// }
//}(subEntryName)

Check failure on line 127 in internal/knowninfo/dwarf.go

View workflow job for this annotation

GitHub Actions / GolangCI Lint

comment-spacings: no space between comment delimiter and comment text (revive)

receiverName = (&gosym.Sym{Name: subEntryName}).ReceiverName()
if receiverName != "" {
typ = entity.FuncTypeMethod
Expand Down
2 changes: 1 addition & 1 deletion scripts/wasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def require_binaryen():
[
opt,
tmp_file.name,
"-O4",
"-O3",
"--enable-bulk-memory",
"-o", wasm_location()
],
Expand Down
48 changes: 35 additions & 13 deletions ui/src/explorer/Explorer.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import type { ReactNode } from "react";
import React, { useEffect, useMemo } from "react";
import { useAsync } from "react-use";
import { Dialog, DialogContent, DialogContentText, DialogTitle } from "@mui/material";
import { Box, Dialog, DialogContent, DialogContentText, DialogTitle } from "@mui/material";
import gsa from "../../gsa.wasm?init";
import { createEntry } from "../tool/entry.ts";
import TreeMap from "../TreeMap.tsx";
import { FileSelector } from "./FileSelector.tsx";

import { resetCallback, setCallback } from "./fs.js";

import "../tool/wasm_exec.js";

type ModalState = {
isOpen: false;
} | {
Expand Down Expand Up @@ -47,6 +51,23 @@ export const Explorer: React.FC = () => {
return gsa_analyze(file.name, uint8);
}, [file]);

const [log, setLog] = React.useState<string>("");

const friendlyLog = useMemo(() => {
if (log === "") {
return "Waiting for log";
}
return log;
}, [log]);

useEffect(() => {
setCallback((line) => {
setLog(log => `${log + line}\n`);
});

return resetCallback;
}, []);

const entry = useMemo(() => {
if (!result) {
return null;
Expand All @@ -69,7 +90,7 @@ export const Explorer: React.FC = () => {
isOpen: true,
title: "Loading",
content:
<DialogContentText>Loading WebAssembly module...</DialogContentText>,
<DialogContentText>Loading WebAssembly module...</DialogContentText>,
});
}
else if (!inst) {
Expand Down Expand Up @@ -98,36 +119,37 @@ export const Explorer: React.FC = () => {
else if (analyzing) {
setModalState({
isOpen: true,
title: "Analyzing",
content: <DialogContentText>Analyzing binary...</DialogContentText>,
title: `Analyzing ${file.name}`,
content: (
<Box fontFamily="monospace" component="pre">
{friendlyLog}
</Box>
),
});
}
else if (!analyzing && !result && !entry) {
setModalState({
isOpen: true,
title: "Error",
title: `Failed to analyze ${file.name}`,
content: (
<DialogContentText>
Failed to analyze
{" "}
{file.name}
, see browser dev console for more details.
</DialogContentText>
<Box fontFamily="monospace" component="pre">
{friendlyLog}
</Box>
),
});
}
else {
setModalState({ isOpen: false });
}
}, [loadError, loading, file, result, analyzing, inst, entry]);
}, [loadError, loading, file, result, analyzing, inst, entry, friendlyLog]);

return (
<>
<Dialog
open={modalState.isOpen}
>
<DialogTitle>{modalState.isOpen && modalState.title}</DialogTitle>
<DialogContent>
<DialogContent dividers>
{modalState.isOpen && modalState.content}
</DialogContent>
</Dialog>
Expand Down
5 changes: 5 additions & 0 deletions ui/src/explorer/fs.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
declare type FSCallback = (line: string) => void;

export declare function setCallback(callback: FSCallback): void;

export declare function resetCallback(): void;
63 changes: 63 additions & 0 deletions ui/src/explorer/fs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
let outputBuf = "";
const decoder = new TextDecoder("utf-8");
function enosys() {
const err = new Error("not implemented");
err.code = "ENOSYS";
return err;
}

const defaultFSCallback = line => console.log(line);

let fsCallback = defaultFSCallback;

export function setCallback(callback) {
fsCallback = callback;
}

export function resetCallback() {
fsCallback = defaultFSCallback;
}

globalThis.fs = {
constants: { O_WRONLY: -1, O_RDWR: -1, O_CREAT: -1, O_TRUNC: -1, O_APPEND: -1, O_EXCL: -1 }, // unused
writeSync(fd, buf) {
outputBuf += decoder.decode(buf);
const nl = outputBuf.lastIndexOf("\n");
if (nl !== -1) {
fsCallback(outputBuf.substring(0, nl));
outputBuf = outputBuf.substring(nl + 1);
}
return buf.length;
},
write(fd, buf, offset, length, position, callback) {
if (offset !== 0 || length !== buf.length || position !== null) {
callback(enosys());
return;
}
const n = this.writeSync(fd, buf);
callback(null, n);
},
chmod(path, mode, callback) { callback(enosys()); },
chown(path, uid, gid, callback) { callback(enosys()); },
close(fd, callback) { callback(enosys()); },
fchmod(fd, mode, callback) { callback(enosys()); },
fchown(fd, uid, gid, callback) { callback(enosys()); },
fstat(fd, callback) { callback(enosys()); },
fsync(fd, callback) { callback(null); },
ftruncate(fd, length, callback) { callback(enosys()); },
lchown(path, uid, gid, callback) { callback(enosys()); },
link(path, link, callback) { callback(enosys()); },
lstat(path, callback) { callback(enosys()); },
mkdir(path, perm, callback) { callback(enosys()); },
open(path, flags, mode, callback) { callback(enosys()); },
read(fd, buffer, offset, length, position, callback) { callback(enosys()); },
readdir(path, callback) { callback(enosys()); },
readlink(path, callback) { callback(enosys()); },
rename(from, to, callback) { callback(enosys()); },
rmdir(path, callback) { callback(enosys()); },
stat(path, callback) { callback(enosys()); },
symlink(path, link, callback) { callback(enosys()); },
truncate(path, length, callback) { callback(enosys()); },
unlink(path, callback) { callback(enosys()); },
utimes(path, atime, mtime, callback) { callback(enosys()); },
};
1 change: 0 additions & 1 deletion ui/src/explorer_main.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import ReactDOM from "react-dom/client";
import React from "react";

import "./tool/wasm_exec.js";
import { Explorer } from "./explorer/Explorer.tsx";

ReactDOM.createRoot(document.getElementById("root")!).render(
Expand Down
4 changes: 3 additions & 1 deletion ui/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
"noUnusedParameters": true,
"noEmit": true,
"isolatedModules": true,
"skipLibCheck": true
"skipLibCheck": true,
"allowJs": true,
"esModuleInterop": true
},
"references": [
{
Expand Down

0 comments on commit ef38d99

Please sign in to comment.